1 /* 2 This is where the abstract matrix operations are defined 3 */ 4 5 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 6 #include <petsc/private/isimpl.h> 7 #include <petsc/private/vecimpl.h> 8 9 /* Logging support */ 10 PetscClassId MAT_CLASSID; 11 PetscClassId MAT_COLORING_CLASSID; 12 PetscClassId MAT_FDCOLORING_CLASSID; 13 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 14 15 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultAdd, MAT_MultTranspose; 16 PetscLogEvent MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 17 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 18 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 19 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 20 PetscLogEvent MAT_QRFactorNumeric, MAT_QRFactorSymbolic, MAT_QRFactor; 21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat; 24 PetscLogEvent MAT_TransposeColoringCreate; 25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols; 32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 34 PetscLogEvent MAT_GetMultiProcBlock; 35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_CUSPARSECopyFromGPU, MAT_CUSPARSEGenerateTranspose, MAT_CUSPARSESolveAnalysis; 36 PetscLogEvent MAT_PreallCOO, MAT_SetVCOO; 37 PetscLogEvent MAT_SetValuesBatch; 38 PetscLogEvent MAT_ViennaCLCopyToGPU; 39 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU; 40 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 41 PetscLogEvent MAT_FactorFactS,MAT_FactorInvS; 42 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 43 PetscLogEvent MAT_H2Opus_Build,MAT_H2Opus_Compress,MAT_H2Opus_Orthog,MAT_H2Opus_LR; 44 45 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","QR","MatFactorType","MAT_FACTOR_",NULL}; 46 47 /*@ 48 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations, 49 for sparse matrices that already have locations it fills the locations with random numbers 50 51 Logically Collective on Mat 52 53 Input Parameters: 54 + x - the matrix 55 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 56 it will create one internally. 57 58 Output Parameter: 59 . x - the matrix 60 61 Example of Usage: 62 .vb 63 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 64 MatSetRandom(x,rctx); 65 PetscRandomDestroy(rctx); 66 .ve 67 68 Level: intermediate 69 70 .seealso: `MatZeroEntries()`, `MatSetValues()`, `PetscRandomCreate()`, `PetscRandomDestroy()` 71 @*/ 72 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 73 { 74 PetscRandom randObj = NULL; 75 76 PetscFunctionBegin; 77 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 78 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 79 PetscValidType(x,1); 80 MatCheckPreallocated(x,1); 81 82 PetscCheck(x->ops->setrandom,PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 83 84 if (!rctx) { 85 MPI_Comm comm; 86 PetscCall(PetscObjectGetComm((PetscObject)x,&comm)); 87 PetscCall(PetscRandomCreate(comm,&randObj)); 88 PetscCall(PetscRandomSetFromOptions(randObj)); 89 rctx = randObj; 90 } 91 PetscCall(PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0)); 92 PetscCall((*x->ops->setrandom)(x,rctx)); 93 PetscCall(PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0)); 94 95 PetscCall(MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY)); 96 PetscCall(MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY)); 97 PetscCall(PetscRandomDestroy(&randObj)); 98 PetscFunctionReturn(0); 99 } 100 101 /*@ 102 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 103 104 Logically Collective on Mat 105 106 Input Parameter: 107 . mat - the factored matrix 108 109 Output Parameters: 110 + pivot - the pivot value computed 111 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 112 the share the matrix 113 114 Level: advanced 115 116 Notes: 117 This routine does not work for factorizations done with external packages. 118 119 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 120 121 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 122 123 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()` 124 @*/ 125 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 126 { 127 PetscFunctionBegin; 128 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 129 PetscValidRealPointer(pivot,2); 130 PetscValidIntPointer(row,3); 131 *pivot = mat->factorerror_zeropivot_value; 132 *row = mat->factorerror_zeropivot_row; 133 PetscFunctionReturn(0); 134 } 135 136 /*@ 137 MatFactorGetError - gets the error code from a factorization 138 139 Logically Collective on Mat 140 141 Input Parameters: 142 . mat - the factored matrix 143 144 Output Parameter: 145 . err - the error code 146 147 Level: advanced 148 149 Notes: 150 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 151 152 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()` 153 @*/ 154 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 155 { 156 PetscFunctionBegin; 157 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 158 PetscValidPointer(err,2); 159 *err = mat->factorerrortype; 160 PetscFunctionReturn(0); 161 } 162 163 /*@ 164 MatFactorClearError - clears the error code in a factorization 165 166 Logically Collective on Mat 167 168 Input Parameter: 169 . mat - the factored matrix 170 171 Level: developer 172 173 Notes: 174 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 175 176 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorGetError()`, `MatFactorGetErrorZeroPivot()` 177 @*/ 178 PetscErrorCode MatFactorClearError(Mat mat) 179 { 180 PetscFunctionBegin; 181 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 182 mat->factorerrortype = MAT_FACTOR_NOERROR; 183 mat->factorerror_zeropivot_value = 0.0; 184 mat->factorerror_zeropivot_row = 0; 185 PetscFunctionReturn(0); 186 } 187 188 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 189 { 190 Vec r,l; 191 const PetscScalar *al; 192 PetscInt i,nz,gnz,N,n; 193 194 PetscFunctionBegin; 195 PetscCall(MatCreateVecs(mat,&r,&l)); 196 if (!cols) { /* nonzero rows */ 197 PetscCall(MatGetSize(mat,&N,NULL)); 198 PetscCall(MatGetLocalSize(mat,&n,NULL)); 199 PetscCall(VecSet(l,0.0)); 200 PetscCall(VecSetRandom(r,NULL)); 201 PetscCall(MatMult(mat,r,l)); 202 PetscCall(VecGetArrayRead(l,&al)); 203 } else { /* nonzero columns */ 204 PetscCall(MatGetSize(mat,NULL,&N)); 205 PetscCall(MatGetLocalSize(mat,NULL,&n)); 206 PetscCall(VecSet(r,0.0)); 207 PetscCall(VecSetRandom(l,NULL)); 208 PetscCall(MatMultTranspose(mat,l,r)); 209 PetscCall(VecGetArrayRead(r,&al)); 210 } 211 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 212 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 213 PetscCall(MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 214 if (gnz != N) { 215 PetscInt *nzr; 216 PetscCall(PetscMalloc1(nz,&nzr)); 217 if (nz) { 218 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 219 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 220 } 221 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero)); 222 } else *nonzero = NULL; 223 if (!cols) { /* nonzero rows */ 224 PetscCall(VecRestoreArrayRead(l,&al)); 225 } else { 226 PetscCall(VecRestoreArrayRead(r,&al)); 227 } 228 PetscCall(VecDestroy(&l)); 229 PetscCall(VecDestroy(&r)); 230 PetscFunctionReturn(0); 231 } 232 233 /*@ 234 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 235 236 Input Parameter: 237 . A - the matrix 238 239 Output Parameter: 240 . keptrows - the rows that are not completely zero 241 242 Notes: 243 keptrows is set to NULL if all rows are nonzero. 244 245 Level: intermediate 246 247 @*/ 248 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 249 { 250 PetscFunctionBegin; 251 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 252 PetscValidType(mat,1); 253 PetscValidPointer(keptrows,2); 254 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 255 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 256 if (mat->ops->findnonzerorows) { 257 PetscCall((*mat->ops->findnonzerorows)(mat,keptrows)); 258 } else { 259 PetscCall(MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows)); 260 } 261 PetscFunctionReturn(0); 262 } 263 264 /*@ 265 MatFindZeroRows - Locate all rows that are completely zero in the matrix 266 267 Input Parameter: 268 . A - the matrix 269 270 Output Parameter: 271 . zerorows - the rows that are completely zero 272 273 Notes: 274 zerorows is set to NULL if no rows are zero. 275 276 Level: intermediate 277 278 @*/ 279 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 280 { 281 IS keptrows; 282 PetscInt m, n; 283 284 PetscFunctionBegin; 285 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 286 PetscValidType(mat,1); 287 PetscValidPointer(zerorows,2); 288 PetscCall(MatFindNonzeroRows(mat, &keptrows)); 289 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 290 In keeping with this convention, we set zerorows to NULL if there are no zero 291 rows. */ 292 if (keptrows == NULL) { 293 *zerorows = NULL; 294 } else { 295 PetscCall(MatGetOwnershipRange(mat,&m,&n)); 296 PetscCall(ISComplement(keptrows,m,n,zerorows)); 297 PetscCall(ISDestroy(&keptrows)); 298 } 299 PetscFunctionReturn(0); 300 } 301 302 /*@ 303 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 304 305 Not Collective 306 307 Input Parameters: 308 . A - the matrix 309 310 Output Parameters: 311 . a - the diagonal part (which is a SEQUENTIAL matrix) 312 313 Notes: 314 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 315 Use caution, as the reference count on the returned matrix is not incremented and it is used as 316 part of the containing MPI Mat's normal operation. 317 318 Level: advanced 319 320 @*/ 321 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 322 { 323 PetscFunctionBegin; 324 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 325 PetscValidType(A,1); 326 PetscValidPointer(a,2); 327 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 328 if (A->ops->getdiagonalblock) { 329 PetscCall((*A->ops->getdiagonalblock)(A,a)); 330 } else { 331 PetscMPIInt size; 332 333 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A),&size)); 334 PetscCheck(size == 1,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not for parallel matrix type %s",((PetscObject)A)->type_name); 335 *a = A; 336 } 337 PetscFunctionReturn(0); 338 } 339 340 /*@ 341 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 342 343 Collective on Mat 344 345 Input Parameters: 346 . mat - the matrix 347 348 Output Parameter: 349 . trace - the sum of the diagonal entries 350 351 Level: advanced 352 353 @*/ 354 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 355 { 356 Vec diag; 357 358 PetscFunctionBegin; 359 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 360 PetscValidScalarPointer(trace,2); 361 PetscCall(MatCreateVecs(mat,&diag,NULL)); 362 PetscCall(MatGetDiagonal(mat,diag)); 363 PetscCall(VecSum(diag,trace)); 364 PetscCall(VecDestroy(&diag)); 365 PetscFunctionReturn(0); 366 } 367 368 /*@ 369 MatRealPart - Zeros out the imaginary part of the matrix 370 371 Logically Collective on Mat 372 373 Input Parameters: 374 . mat - the matrix 375 376 Level: advanced 377 378 .seealso: `MatImaginaryPart()` 379 @*/ 380 PetscErrorCode MatRealPart(Mat mat) 381 { 382 PetscFunctionBegin; 383 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 384 PetscValidType(mat,1); 385 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 386 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 387 PetscCheck(mat->ops->realpart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 388 MatCheckPreallocated(mat,1); 389 PetscCall((*mat->ops->realpart)(mat)); 390 PetscFunctionReturn(0); 391 } 392 393 /*@C 394 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 395 396 Collective on Mat 397 398 Input Parameter: 399 . mat - the matrix 400 401 Output Parameters: 402 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 403 - ghosts - the global indices of the ghost points 404 405 Notes: 406 the nghosts and ghosts are suitable to pass into VecCreateGhost() 407 408 Level: advanced 409 410 @*/ 411 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 412 { 413 PetscFunctionBegin; 414 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 415 PetscValidType(mat,1); 416 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 417 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 418 if (mat->ops->getghosts) { 419 PetscCall((*mat->ops->getghosts)(mat,nghosts,ghosts)); 420 } else { 421 if (nghosts) *nghosts = 0; 422 if (ghosts) *ghosts = NULL; 423 } 424 PetscFunctionReturn(0); 425 } 426 427 /*@ 428 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 429 430 Logically Collective on Mat 431 432 Input Parameters: 433 . mat - the matrix 434 435 Level: advanced 436 437 .seealso: `MatRealPart()` 438 @*/ 439 PetscErrorCode MatImaginaryPart(Mat mat) 440 { 441 PetscFunctionBegin; 442 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 443 PetscValidType(mat,1); 444 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 445 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 446 PetscCheck(mat->ops->imaginarypart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 447 MatCheckPreallocated(mat,1); 448 PetscCall((*mat->ops->imaginarypart)(mat)); 449 PetscFunctionReturn(0); 450 } 451 452 /*@ 453 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 454 455 Not Collective 456 457 Input Parameter: 458 . mat - the matrix 459 460 Output Parameters: 461 + missing - is any diagonal missing 462 - dd - first diagonal entry that is missing (optional) on this process 463 464 Level: advanced 465 466 .seealso: `MatRealPart()` 467 @*/ 468 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 469 { 470 PetscFunctionBegin; 471 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 472 PetscValidType(mat,1); 473 PetscValidBoolPointer(missing,2); 474 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name); 475 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 476 PetscCheck(mat->ops->missingdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 477 PetscCall((*mat->ops->missingdiagonal)(mat,missing,dd)); 478 PetscFunctionReturn(0); 479 } 480 481 /*@C 482 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 483 for each row that you get to ensure that your application does 484 not bleed memory. 485 486 Not Collective 487 488 Input Parameters: 489 + mat - the matrix 490 - row - the row to get 491 492 Output Parameters: 493 + ncols - if not NULL, the number of nonzeros in the row 494 . cols - if not NULL, the column numbers 495 - vals - if not NULL, the values 496 497 Notes: 498 This routine is provided for people who need to have direct access 499 to the structure of a matrix. We hope that we provide enough 500 high-level matrix routines that few users will need it. 501 502 MatGetRow() always returns 0-based column indices, regardless of 503 whether the internal representation is 0-based (default) or 1-based. 504 505 For better efficiency, set cols and/or vals to NULL if you do 506 not wish to extract these quantities. 507 508 The user can only examine the values extracted with MatGetRow(); 509 the values cannot be altered. To change the matrix entries, one 510 must use MatSetValues(). 511 512 You can only have one call to MatGetRow() outstanding for a particular 513 matrix at a time, per processor. MatGetRow() can only obtain rows 514 associated with the given processor, it cannot get rows from the 515 other processors; for that we suggest using MatCreateSubMatrices(), then 516 MatGetRow() on the submatrix. The row index passed to MatGetRow() 517 is in the global number of rows. 518 519 Fortran Notes: 520 The calling sequence from Fortran is 521 .vb 522 MatGetRow(matrix,row,ncols,cols,values,ierr) 523 Mat matrix (input) 524 integer row (input) 525 integer ncols (output) 526 integer cols(maxcols) (output) 527 double precision (or double complex) values(maxcols) output 528 .ve 529 where maxcols >= maximum nonzeros in any row of the matrix. 530 531 Caution: 532 Do not try to change the contents of the output arrays (cols and vals). 533 In some cases, this may corrupt the matrix. 534 535 Level: advanced 536 537 .seealso: `MatRestoreRow()`, `MatSetValues()`, `MatGetValues()`, `MatCreateSubMatrices()`, `MatGetDiagonal()` 538 @*/ 539 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 540 { 541 PetscInt incols; 542 543 PetscFunctionBegin; 544 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 545 PetscValidType(mat,1); 546 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 547 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 548 PetscCheck(mat->ops->getrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 549 MatCheckPreallocated(mat,1); 550 PetscCheck(row >= mat->rmap->rstart && row < mat->rmap->rend,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Only for local rows, %" PetscInt_FMT " not in [%" PetscInt_FMT ",%" PetscInt_FMT ")",row,mat->rmap->rstart,mat->rmap->rend); 551 PetscCall(PetscLogEventBegin(MAT_GetRow,mat,0,0,0)); 552 PetscCall((*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals)); 553 if (ncols) *ncols = incols; 554 PetscCall(PetscLogEventEnd(MAT_GetRow,mat,0,0,0)); 555 PetscFunctionReturn(0); 556 } 557 558 /*@ 559 MatConjugate - replaces the matrix values with their complex conjugates 560 561 Logically Collective on Mat 562 563 Input Parameters: 564 . mat - the matrix 565 566 Level: advanced 567 568 .seealso: `VecConjugate()` 569 @*/ 570 PetscErrorCode MatConjugate(Mat mat) 571 { 572 PetscFunctionBegin; 573 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 574 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 575 if (PetscDefined(USE_COMPLEX)) { 576 PetscCheck(mat->ops->conjugate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for matrix type %s, send email to petsc-maint@mcs.anl.gov",((PetscObject)mat)->type_name); 577 PetscCall((*mat->ops->conjugate)(mat)); 578 } 579 PetscFunctionReturn(0); 580 } 581 582 /*@C 583 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 584 585 Not Collective 586 587 Input Parameters: 588 + mat - the matrix 589 . row - the row to get 590 . ncols, cols - the number of nonzeros and their columns 591 - vals - if nonzero the column values 592 593 Notes: 594 This routine should be called after you have finished examining the entries. 595 596 This routine zeros out ncols, cols, and vals. This is to prevent accidental 597 us of the array after it has been restored. If you pass NULL, it will 598 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 599 600 Fortran Notes: 601 The calling sequence from Fortran is 602 .vb 603 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 604 Mat matrix (input) 605 integer row (input) 606 integer ncols (output) 607 integer cols(maxcols) (output) 608 double precision (or double complex) values(maxcols) output 609 .ve 610 Where maxcols >= maximum nonzeros in any row of the matrix. 611 612 In Fortran MatRestoreRow() MUST be called after MatGetRow() 613 before another call to MatGetRow() can be made. 614 615 Level: advanced 616 617 .seealso: `MatGetRow()` 618 @*/ 619 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 620 { 621 PetscFunctionBegin; 622 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 623 if (ncols) PetscValidIntPointer(ncols,3); 624 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 625 if (!mat->ops->restorerow) PetscFunctionReturn(0); 626 PetscCall((*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals)); 627 if (ncols) *ncols = 0; 628 if (cols) *cols = NULL; 629 if (vals) *vals = NULL; 630 PetscFunctionReturn(0); 631 } 632 633 /*@ 634 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 635 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 636 637 Not Collective 638 639 Input Parameters: 640 . mat - the matrix 641 642 Notes: 643 The flag is to ensure that users are aware of MatGetRow() only provides the upper triangular part of the row for the matrices in MATSBAIJ format. 644 645 Level: advanced 646 647 .seealso: `MatRestoreRowUpperTriangular()` 648 @*/ 649 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 650 { 651 PetscFunctionBegin; 652 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 653 PetscValidType(mat,1); 654 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 655 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 656 MatCheckPreallocated(mat,1); 657 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 658 PetscCall((*mat->ops->getrowuppertriangular)(mat)); 659 PetscFunctionReturn(0); 660 } 661 662 /*@ 663 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 664 665 Not Collective 666 667 Input Parameters: 668 . mat - the matrix 669 670 Notes: 671 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 672 673 Level: advanced 674 675 .seealso: `MatGetRowUpperTriangular()` 676 @*/ 677 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 678 { 679 PetscFunctionBegin; 680 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 681 PetscValidType(mat,1); 682 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 683 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 684 MatCheckPreallocated(mat,1); 685 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 686 PetscCall((*mat->ops->restorerowuppertriangular)(mat)); 687 PetscFunctionReturn(0); 688 } 689 690 /*@C 691 MatSetOptionsPrefix - Sets the prefix used for searching for all 692 Mat options in the database. 693 694 Logically Collective on Mat 695 696 Input Parameters: 697 + A - the Mat context 698 - prefix - the prefix to prepend to all option names 699 700 Notes: 701 A hyphen (-) must NOT be given at the beginning of the prefix name. 702 The first character of all runtime options is AUTOMATICALLY the hyphen. 703 704 This is NOT used for options for the factorization of the matrix. Normally the 705 prefix is automatically passed in from the PC calling the factorization. To set 706 it directly use `MatSetOptionsPrefixFactor()` 707 708 Level: advanced 709 710 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefixFactor()` 711 @*/ 712 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 713 { 714 PetscFunctionBegin; 715 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 716 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)A,prefix)); 717 PetscFunctionReturn(0); 718 } 719 720 /*@C 721 MatSetOptionsPrefixFactor - Sets the prefix used for searching for all Mat factor options in the database for 722 for matrices created with `MatGetFactor()` 723 724 Logically Collective on Mat 725 726 Input Parameters: 727 + A - the Mat context 728 - prefix - the prefix to prepend to all option names for the factored matrix 729 730 Notes: 731 A hyphen (-) must NOT be given at the beginning of the prefix name. 732 The first character of all runtime options is AUTOMATICALLY the hyphen. 733 734 Normally the prefix is automatically passed in from the PC calling the factorization. To set 735 it directly when not using `KSP`/`PC` use `MatSetOptionsPrefixFactor()` 736 737 Level: developer 738 739 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()` 740 @*/ 741 PetscErrorCode MatSetOptionsPrefixFactor(Mat A,const char prefix[]) 742 { 743 PetscFunctionBegin; 744 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 745 if (prefix) { 746 PetscValidCharPointer(prefix,2); 747 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 748 if (prefix != A->factorprefix) { 749 PetscCall(PetscFree(A->factorprefix)); 750 PetscCall(PetscStrallocpy(prefix,&A->factorprefix)); 751 } 752 } else PetscCall(PetscFree(A->factorprefix)); 753 PetscFunctionReturn(0); 754 } 755 756 /*@C 757 MatAppendOptionsPrefixFactor - Appends to the prefix used for searching for all Mat factor options in the database for 758 for matrices created with `MatGetFactor()` 759 760 Logically Collective on Mat 761 762 Input Parameters: 763 + A - the Mat context 764 - prefix - the prefix to prepend to all option names for the factored matrix 765 766 Notes: 767 A hyphen (-) must NOT be given at the beginning of the prefix name. 768 The first character of all runtime options is AUTOMATICALLY the hyphen. 769 770 Normally the prefix is automatically passed in from the PC calling the factorization. To set 771 it directly when not using `KSP`/`PC` use `MatAppendOptionsPrefixFactor()` 772 773 Level: developer 774 .seealso: `PetscOptionsCreate()`, `PetscOptionsDestroy()`, `PetscObjectSetOptionsPrefix()`, `PetscObjectPrependOptionsPrefix()`, 775 `PetscObjectGetOptionsPrefix()`, `TSAppendOptionsPrefix()`, `SNESAppendOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `MatSetOptionsPrefixFactor()`, 776 `MatSetOptionsPrefix()` 777 @*/ 778 PetscErrorCode MatAppendOptionsPrefixFactor(Mat A,const char prefix[]) 779 { 780 char *buf = A->factorprefix; 781 size_t len1,len2; 782 783 PetscFunctionBegin; 784 PetscValidHeader(A,1); 785 if (!prefix) PetscFunctionReturn(0); 786 if (!buf) { 787 PetscCall(MatSetOptionsPrefixFactor(A,prefix)); 788 PetscFunctionReturn(0); 789 } 790 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 791 792 PetscCall(PetscStrlen(prefix,&len1)); 793 PetscCall(PetscStrlen(buf,&len2)); 794 PetscCall(PetscMalloc1(1+len1+len2,&A->factorprefix)); 795 PetscCall(PetscStrcpy(A->factorprefix,buf)); 796 PetscCall(PetscStrcat(A->factorprefix,prefix)); 797 PetscCall(PetscFree(buf)); 798 PetscFunctionReturn(0); 799 } 800 801 /*@C 802 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 803 Mat options in the database. 804 805 Logically Collective on Mat 806 807 Input Parameters: 808 + A - the Mat context 809 - prefix - the prefix to prepend to all option names 810 811 Notes: 812 A hyphen (-) must NOT be given at the beginning of the prefix name. 813 The first character of all runtime options is AUTOMATICALLY the hyphen. 814 815 Level: advanced 816 817 .seealso: `MatGetOptionsPrefix()` 818 @*/ 819 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 820 { 821 PetscFunctionBegin; 822 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 823 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)A,prefix)); 824 PetscFunctionReturn(0); 825 } 826 827 /*@C 828 MatGetOptionsPrefix - Gets the prefix used for searching for all 829 Mat options in the database. 830 831 Not Collective 832 833 Input Parameter: 834 . A - the Mat context 835 836 Output Parameter: 837 . prefix - pointer to the prefix string used 838 839 Notes: 840 On the fortran side, the user should pass in a string 'prefix' of 841 sufficient length to hold the prefix. 842 843 Level: advanced 844 845 .seealso: `MatAppendOptionsPrefix()` 846 @*/ 847 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 848 { 849 PetscFunctionBegin; 850 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 851 PetscValidPointer(prefix,2); 852 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)A,prefix)); 853 PetscFunctionReturn(0); 854 } 855 856 /*@ 857 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 858 859 Collective on Mat 860 861 Input Parameters: 862 . A - the Mat context 863 864 Notes: 865 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 866 Currently support MPIAIJ and SEQAIJ. 867 868 Level: beginner 869 870 .seealso: `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatXAIJSetPreallocation()` 871 @*/ 872 PetscErrorCode MatResetPreallocation(Mat A) 873 { 874 PetscFunctionBegin; 875 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 876 PetscValidType(A,1); 877 PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A)); 878 PetscFunctionReturn(0); 879 } 880 881 /*@ 882 MatSetUp - Sets up the internal matrix data structures for later use. 883 884 Collective on Mat 885 886 Input Parameters: 887 . A - the Mat context 888 889 Notes: 890 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 891 892 If a suitable preallocation routine is used, this function does not need to be called. 893 894 See the Performance chapter of the PETSc users manual for how to preallocate matrices 895 896 Level: beginner 897 898 .seealso: `MatCreate()`, `MatDestroy()` 899 @*/ 900 PetscErrorCode MatSetUp(Mat A) 901 { 902 PetscFunctionBegin; 903 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 904 if (!((PetscObject)A)->type_name) { 905 PetscMPIInt size; 906 907 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 908 PetscCall(MatSetType(A, size == 1 ? MATSEQAIJ : MATMPIAIJ)); 909 } 910 if (!A->preallocated && A->ops->setup) { 911 PetscCall(PetscInfo(A,"Warning not preallocating matrix storage\n")); 912 PetscCall((*A->ops->setup)(A)); 913 } 914 PetscCall(PetscLayoutSetUp(A->rmap)); 915 PetscCall(PetscLayoutSetUp(A->cmap)); 916 A->preallocated = PETSC_TRUE; 917 PetscFunctionReturn(0); 918 } 919 920 #if defined(PETSC_HAVE_SAWS) 921 #include <petscviewersaws.h> 922 #endif 923 924 /*@C 925 MatViewFromOptions - View from Options 926 927 Collective on Mat 928 929 Input Parameters: 930 + A - the Mat context 931 . obj - Optional object 932 - name - command line option 933 934 Level: intermediate 935 .seealso: `Mat`, `MatView`, `PetscObjectViewFromOptions()`, `MatCreate()` 936 @*/ 937 PetscErrorCode MatViewFromOptions(Mat A,PetscObject obj,const char name[]) 938 { 939 PetscFunctionBegin; 940 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 941 PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 942 PetscFunctionReturn(0); 943 } 944 945 /*@C 946 MatView - Visualizes a matrix object. 947 948 Collective on Mat 949 950 Input Parameters: 951 + mat - the matrix 952 - viewer - visualization context 953 954 Notes: 955 The available visualization contexts include 956 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 957 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 958 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 959 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 960 961 The user can open alternative visualization contexts with 962 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 963 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 964 specified file; corresponding input uses MatLoad() 965 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 966 an X window display 967 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 968 Currently only the sequential dense and AIJ 969 matrix types support the Socket viewer. 970 971 The user can call PetscViewerPushFormat() to specify the output 972 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 973 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 974 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 975 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 976 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 977 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 978 format common among all matrix types 979 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 980 format (which is in many cases the same as the default) 981 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 982 size and structure (not the matrix entries) 983 - PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 984 the matrix structure 985 986 Options Database Keys: 987 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 988 . -mat_view ::ascii_info_detail - Prints more detailed info 989 . -mat_view - Prints matrix in ASCII format 990 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 991 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 992 . -display <name> - Sets display name (default is host) 993 . -draw_pause <sec> - Sets number of seconds to pause after display 994 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 995 . -viewer_socket_machine <machine> - 996 . -viewer_socket_port <port> - 997 . -mat_view binary - save matrix to file in binary format 998 - -viewer_binary_filename <name> - 999 1000 Level: beginner 1001 1002 Notes: 1003 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 1004 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 1005 1006 In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer). 1007 1008 See the manual page for MatLoad() for the exact format of the binary file when the binary 1009 viewer is used. 1010 1011 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 1012 viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python. 1013 1014 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 1015 and then use the following mouse functions. 1016 .vb 1017 left mouse: zoom in 1018 middle mouse: zoom out 1019 right mouse: continue with the simulation 1020 .ve 1021 1022 .seealso: `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, 1023 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `MatLoad()` 1024 @*/ 1025 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 1026 { 1027 PetscInt rows,cols,rbs,cbs; 1028 PetscBool isascii,isstring,issaws; 1029 PetscViewerFormat format; 1030 PetscMPIInt size; 1031 1032 PetscFunctionBegin; 1033 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1034 PetscValidType(mat,1); 1035 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer)); 1036 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1037 PetscCheckSameComm(mat,1,viewer,2); 1038 MatCheckPreallocated(mat,1); 1039 1040 PetscCall(PetscViewerGetFormat(viewer,&format)); 1041 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 1042 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 1043 1044 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring)); 1045 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii)); 1046 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws)); 1047 if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1048 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detail"); 1049 } 1050 1051 PetscCall(PetscLogEventBegin(MAT_View,mat,viewer,0,0)); 1052 if (isascii) { 1053 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1054 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer)); 1055 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1056 MatNullSpace nullsp,transnullsp; 1057 1058 PetscCall(PetscViewerASCIIPushTab(viewer)); 1059 PetscCall(MatGetSize(mat,&rows,&cols)); 1060 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1061 if (rbs != 1 || cbs != 1) { 1062 if (rbs != cbs) PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", rbs=%" PetscInt_FMT ", cbs=%" PetscInt_FMT "\n",rows,cols,rbs,cbs)); 1063 else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n",rows,cols,rbs)); 1064 } else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT "\n",rows,cols)); 1065 if (mat->factortype) { 1066 MatSolverType solver; 1067 PetscCall(MatFactorGetSolverType(mat,&solver)); 1068 PetscCall(PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver)); 1069 } 1070 if (mat->ops->getinfo) { 1071 MatInfo info; 1072 PetscCall(MatGetInfo(mat,MAT_GLOBAL_SUM,&info)); 1073 PetscCall(PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated)); 1074 if (!mat->factortype) PetscCall(PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%" PetscInt_FMT "\n",(PetscInt)info.mallocs)); 1075 } 1076 PetscCall(MatGetNullSpace(mat,&nullsp)); 1077 PetscCall(MatGetTransposeNullSpace(mat,&transnullsp)); 1078 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached null space\n")); 1079 if (transnullsp && transnullsp != nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached transposed null space\n")); 1080 PetscCall(MatGetNearNullSpace(mat,&nullsp)); 1081 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached near null space\n")); 1082 PetscCall(PetscViewerASCIIPushTab(viewer)); 1083 PetscCall(MatProductView(mat,viewer)); 1084 PetscCall(PetscViewerASCIIPopTab(viewer)); 1085 } 1086 } else if (issaws) { 1087 #if defined(PETSC_HAVE_SAWS) 1088 PetscMPIInt rank; 1089 1090 PetscCall(PetscObjectName((PetscObject)mat)); 1091 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 1092 if (!((PetscObject)mat)->amsmem && rank == 0) { 1093 PetscCall(PetscObjectViewSAWs((PetscObject)mat,viewer)); 1094 } 1095 #endif 1096 } else if (isstring) { 1097 const char *type; 1098 PetscCall(MatGetType(mat,&type)); 1099 PetscCall(PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type)); 1100 if (mat->ops->view) PetscCall((*mat->ops->view)(mat,viewer)); 1101 } 1102 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1103 PetscCall(PetscViewerASCIIPushTab(viewer)); 1104 PetscCall((*mat->ops->viewnative)(mat,viewer)); 1105 PetscCall(PetscViewerASCIIPopTab(viewer)); 1106 } else if (mat->ops->view) { 1107 PetscCall(PetscViewerASCIIPushTab(viewer)); 1108 PetscCall((*mat->ops->view)(mat,viewer)); 1109 PetscCall(PetscViewerASCIIPopTab(viewer)); 1110 } 1111 if (isascii) { 1112 PetscCall(PetscViewerGetFormat(viewer,&format)); 1113 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1114 PetscCall(PetscViewerASCIIPopTab(viewer)); 1115 } 1116 } 1117 PetscCall(PetscLogEventEnd(MAT_View,mat,viewer,0,0)); 1118 PetscFunctionReturn(0); 1119 } 1120 1121 #if defined(PETSC_USE_DEBUG) 1122 #include <../src/sys/totalview/tv_data_display.h> 1123 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1124 { 1125 TV_add_row("Local rows", "int", &mat->rmap->n); 1126 TV_add_row("Local columns", "int", &mat->cmap->n); 1127 TV_add_row("Global rows", "int", &mat->rmap->N); 1128 TV_add_row("Global columns", "int", &mat->cmap->N); 1129 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1130 return TV_format_OK; 1131 } 1132 #endif 1133 1134 /*@C 1135 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1136 with MatView(). The matrix format is determined from the options database. 1137 Generates a parallel MPI matrix if the communicator has more than one 1138 processor. The default matrix type is AIJ. 1139 1140 Collective on PetscViewer 1141 1142 Input Parameters: 1143 + mat - the newly loaded matrix, this needs to have been created with MatCreate() 1144 or some related function before a call to MatLoad() 1145 - viewer - binary/HDF5 file viewer 1146 1147 Options Database Keys: 1148 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1149 block size 1150 . -matload_block_size <bs> - set block size 1151 1152 Level: beginner 1153 1154 Notes: 1155 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1156 Mat before calling this routine if you wish to set it from the options database. 1157 1158 MatLoad() automatically loads into the options database any options 1159 given in the file filename.info where filename is the name of the file 1160 that was passed to the PetscViewerBinaryOpen(). The options in the info 1161 file will be ignored if you use the -viewer_binary_skip_info option. 1162 1163 If the type or size of mat is not set before a call to MatLoad, PETSc 1164 sets the default matrix type AIJ and sets the local and global sizes. 1165 If type and/or size is already set, then the same are used. 1166 1167 In parallel, each processor can load a subset of rows (or the 1168 entire matrix). This routine is especially useful when a large 1169 matrix is stored on disk and only part of it is desired on each 1170 processor. For example, a parallel solver may access only some of 1171 the rows from each processor. The algorithm used here reads 1172 relatively small blocks of data rather than reading the entire 1173 matrix and then subsetting it. 1174 1175 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5. 1176 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(), 1177 or the sequence like 1178 $ PetscViewer v; 1179 $ PetscViewerCreate(PETSC_COMM_WORLD,&v); 1180 $ PetscViewerSetType(v,PETSCVIEWERBINARY); 1181 $ PetscViewerSetFromOptions(v); 1182 $ PetscViewerFileSetMode(v,FILE_MODE_READ); 1183 $ PetscViewerFileSetName(v,"datafile"); 1184 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option 1185 $ -viewer_type {binary,hdf5} 1186 1187 See the example src/ksp/ksp/tutorials/ex27.c with the first approach, 1188 and src/mat/tutorials/ex10.c with the second approach. 1189 1190 Notes about the PETSc binary format: 1191 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks 1192 is read onto rank 0 and then shipped to its destination rank, one after another. 1193 Multiple objects, both matrices and vectors, can be stored within the same file. 1194 Their PetscObject name is ignored; they are loaded in the order of their storage. 1195 1196 Most users should not need to know the details of the binary storage 1197 format, since MatLoad() and MatView() completely hide these details. 1198 But for anyone who's interested, the standard binary matrix storage 1199 format is 1200 1201 $ PetscInt MAT_FILE_CLASSID 1202 $ PetscInt number of rows 1203 $ PetscInt number of columns 1204 $ PetscInt total number of nonzeros 1205 $ PetscInt *number nonzeros in each row 1206 $ PetscInt *column indices of all nonzeros (starting index is zero) 1207 $ PetscScalar *values of all nonzeros 1208 1209 PETSc automatically does the byte swapping for 1210 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1211 Linux, Microsoft Windows and the Intel Paragon; thus if you write your own binary 1212 read/write routines you have to swap the bytes; see PetscBinaryRead() 1213 and PetscBinaryWrite() to see how this may be done. 1214 1215 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1216 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used. 1217 Each processor's chunk is loaded independently by its owning rank. 1218 Multiple objects, both matrices and vectors, can be stored within the same file. 1219 They are looked up by their PetscObject name. 1220 1221 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1222 by default the same structure and naming of the AIJ arrays and column count 1223 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1224 $ save example.mat A b -v7.3 1225 can be directly read by this routine (see Reference 1 for details). 1226 Note that depending on your MATLAB version, this format might be a default, 1227 otherwise you can set it as default in Preferences. 1228 1229 Unless -nocompression flag is used to save the file in MATLAB, 1230 PETSc must be configured with ZLIB package. 1231 1232 See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c 1233 1234 Current HDF5 (MAT-File) limitations: 1235 This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices. 1236 1237 Corresponding MatView() is not yet implemented. 1238 1239 The loaded matrix is actually a transpose of the original one in MATLAB, 1240 unless you push PETSC_VIEWER_HDF5_MAT format (see examples above). 1241 With this format, matrix is automatically transposed by PETSc, 1242 unless the matrix is marked as SPD or symmetric 1243 (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC). 1244 1245 References: 1246 . * - MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1247 1248 .seealso: `PetscViewerBinaryOpen()`, `PetscViewerSetType()`, `MatView()`, `VecLoad()` 1249 1250 @*/ 1251 PetscErrorCode MatLoad(Mat mat,PetscViewer viewer) 1252 { 1253 PetscBool flg; 1254 1255 PetscFunctionBegin; 1256 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1257 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1258 1259 if (!((PetscObject)mat)->type_name) PetscCall(MatSetType(mat,MATAIJ)); 1260 1261 flg = PETSC_FALSE; 1262 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_symmetric",&flg,NULL)); 1263 if (flg) { 1264 PetscCall(MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)); 1265 PetscCall(MatSetOption(mat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE)); 1266 } 1267 flg = PETSC_FALSE; 1268 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_spd",&flg,NULL)); 1269 if (flg) PetscCall(MatSetOption(mat,MAT_SPD,PETSC_TRUE)); 1270 1271 PetscCheck(mat->ops->load,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)mat)->type_name); 1272 PetscCall(PetscLogEventBegin(MAT_Load,mat,viewer,0,0)); 1273 PetscCall((*mat->ops->load)(mat,viewer)); 1274 PetscCall(PetscLogEventEnd(MAT_Load,mat,viewer,0,0)); 1275 PetscFunctionReturn(0); 1276 } 1277 1278 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1279 { 1280 Mat_Redundant *redund = *redundant; 1281 1282 PetscFunctionBegin; 1283 if (redund) { 1284 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1285 PetscCall(ISDestroy(&redund->isrow)); 1286 PetscCall(ISDestroy(&redund->iscol)); 1287 PetscCall(MatDestroySubMatrices(1,&redund->matseq)); 1288 } else { 1289 PetscCall(PetscFree2(redund->send_rank,redund->recv_rank)); 1290 PetscCall(PetscFree(redund->sbuf_j)); 1291 PetscCall(PetscFree(redund->sbuf_a)); 1292 for (PetscInt i=0; i<redund->nrecvs; i++) { 1293 PetscCall(PetscFree(redund->rbuf_j[i])); 1294 PetscCall(PetscFree(redund->rbuf_a[i])); 1295 } 1296 PetscCall(PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a)); 1297 } 1298 1299 if (redund->subcomm) PetscCall(PetscCommDestroy(&redund->subcomm)); 1300 PetscCall(PetscFree(redund)); 1301 } 1302 PetscFunctionReturn(0); 1303 } 1304 1305 /*@C 1306 MatDestroy - Frees space taken by a matrix. 1307 1308 Collective on Mat 1309 1310 Input Parameter: 1311 . A - the matrix 1312 1313 Level: beginner 1314 1315 Developer Notes: 1316 Some special arrays of matrices are not destroyed in this routine but instead by the routines called by 1317 MatDestroySubMatrices(). Thus one must be sure that any changes here must also be made in those routines. 1318 MatHeaderMerge() and MatHeaderReplace() also manipulate the data in the Mat object and likely need changes 1319 if changes are needed here. 1320 @*/ 1321 PetscErrorCode MatDestroy(Mat *A) 1322 { 1323 PetscFunctionBegin; 1324 if (!*A) PetscFunctionReturn(0); 1325 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1326 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1327 1328 /* if memory was published with SAWs then destroy it */ 1329 PetscCall(PetscObjectSAWsViewOff((PetscObject)*A)); 1330 if ((*A)->ops->destroy) PetscCall((*(*A)->ops->destroy)(*A)); 1331 1332 PetscCall(PetscFree((*A)->factorprefix)); 1333 PetscCall(PetscFree((*A)->defaultvectype)); 1334 PetscCall(PetscFree((*A)->bsizes)); 1335 PetscCall(PetscFree((*A)->solvertype)); 1336 for (PetscInt i=0; i<MAT_FACTOR_NUM_TYPES; i++) PetscCall(PetscFree((*A)->preferredordering[i])); 1337 if ((*A)->redundant && (*A)->redundant->matseq[0] == *A) (*A)->redundant->matseq[0] = NULL; 1338 PetscCall(MatDestroy_Redundant(&(*A)->redundant)); 1339 PetscCall(MatProductClear(*A)); 1340 PetscCall(MatNullSpaceDestroy(&(*A)->nullsp)); 1341 PetscCall(MatNullSpaceDestroy(&(*A)->transnullsp)); 1342 PetscCall(MatNullSpaceDestroy(&(*A)->nearnullsp)); 1343 PetscCall(MatDestroy(&(*A)->schur)); 1344 PetscCall(PetscLayoutDestroy(&(*A)->rmap)); 1345 PetscCall(PetscLayoutDestroy(&(*A)->cmap)); 1346 PetscCall(PetscHeaderDestroy(A)); 1347 PetscFunctionReturn(0); 1348 } 1349 1350 /*@C 1351 MatSetValues - Inserts or adds a block of values into a matrix. 1352 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1353 MUST be called after all calls to MatSetValues() have been completed. 1354 1355 Not Collective 1356 1357 Input Parameters: 1358 + mat - the matrix 1359 . v - a logically two-dimensional array of values 1360 . m, idxm - the number of rows and their global indices 1361 . n, idxn - the number of columns and their global indices 1362 - addv - either ADD_VALUES or INSERT_VALUES, where 1363 ADD_VALUES adds values to any existing entries, and 1364 INSERT_VALUES replaces existing entries with new values 1365 1366 Notes: 1367 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1368 MatSetUp() before using this routine 1369 1370 By default the values, v, are row-oriented. See MatSetOption() for other options. 1371 1372 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1373 options cannot be mixed without intervening calls to the assembly 1374 routines. 1375 1376 MatSetValues() uses 0-based row and column numbers in Fortran 1377 as well as in C. 1378 1379 Negative indices may be passed in idxm and idxn, these rows and columns are 1380 simply ignored. This allows easily inserting element stiffness matrices 1381 with homogeneous Dirchlet boundary conditions that you don't want represented 1382 in the matrix. 1383 1384 Efficiency Alert: 1385 The routine MatSetValuesBlocked() may offer much better efficiency 1386 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1387 1388 Level: beginner 1389 1390 Developer Notes: 1391 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1392 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1393 1394 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1395 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 1396 @*/ 1397 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1398 { 1399 PetscFunctionBeginHot; 1400 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1401 PetscValidType(mat,1); 1402 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1403 PetscValidIntPointer(idxm,3); 1404 PetscValidIntPointer(idxn,5); 1405 MatCheckPreallocated(mat,1); 1406 1407 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1408 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1409 1410 if (PetscDefined(USE_DEBUG)) { 1411 PetscInt i,j; 1412 1413 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1414 PetscCheck(mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1415 1416 for (i=0; i<m; i++) { 1417 for (j=0; j<n; j++) { 1418 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1419 #if defined(PETSC_USE_COMPLEX) 1420 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+i%g at matrix entry (%" PetscInt_FMT ",%" PetscInt_FMT ")",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]); 1421 #else 1422 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%" PetscInt_FMT ",%" PetscInt_FMT ")",(double)v[i*n+j],idxm[i],idxn[j]); 1423 #endif 1424 } 1425 } 1426 for (i=0; i<m; i++) PetscCheck(idxm[i] < mat->rmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in row %" PetscInt_FMT ", maximum is %" PetscInt_FMT,idxm[i],mat->rmap->N-1); 1427 for (i=0; i<n; i++) PetscCheck(idxn[i] < mat->cmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in column %" PetscInt_FMT ", maximum is %" PetscInt_FMT,idxn[i],mat->cmap->N-1); 1428 } 1429 1430 if (mat->assembled) { 1431 mat->was_assembled = PETSC_TRUE; 1432 mat->assembled = PETSC_FALSE; 1433 } 1434 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1435 PetscCall((*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv)); 1436 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1437 PetscFunctionReturn(0); 1438 } 1439 1440 /*@C 1441 MatSetValuesIS - Inserts or adds a block of values into a matrix using IS to indicate the rows and columns 1442 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1443 MUST be called after all calls to MatSetValues() have been completed. 1444 1445 Not Collective 1446 1447 Input Parameters: 1448 + mat - the matrix 1449 . v - a logically two-dimensional array of values 1450 . ism - the rows to provide 1451 . isn - the columns to provide 1452 - addv - either ADD_VALUES or INSERT_VALUES, where 1453 ADD_VALUES adds values to any existing entries, and 1454 INSERT_VALUES replaces existing entries with new values 1455 1456 Notes: 1457 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1458 MatSetUp() before using this routine 1459 1460 By default the values, v, are row-oriented. See MatSetOption() for other options. 1461 1462 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1463 options cannot be mixed without intervening calls to the assembly 1464 routines. 1465 1466 MatSetValues() uses 0-based row and column numbers in Fortran 1467 as well as in C. 1468 1469 Negative indices may be passed in ism and isn, these rows and columns are 1470 simply ignored. This allows easily inserting element stiffness matrices 1471 with homogeneous Dirchlet boundary conditions that you don't want represented 1472 in the matrix. 1473 1474 Efficiency Alert: 1475 The routine MatSetValuesBlocked() may offer much better efficiency 1476 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1477 1478 Level: beginner 1479 1480 Developer Notes: 1481 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1482 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1483 1484 This is currently not optimized for any particular IS type 1485 1486 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1487 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1488 @*/ 1489 PetscErrorCode MatSetValuesIS(Mat mat,IS ism,IS isn,const PetscScalar v[],InsertMode addv) 1490 { 1491 PetscInt m,n; 1492 const PetscInt *rows,*cols; 1493 1494 PetscFunctionBeginHot; 1495 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1496 PetscCall(ISGetIndices(ism,&rows)); 1497 PetscCall(ISGetIndices(isn,&cols)); 1498 PetscCall(ISGetLocalSize(ism,&m)); 1499 PetscCall(ISGetLocalSize(isn,&n)); 1500 PetscCall(MatSetValues(mat,m,rows,n,cols,v,addv)); 1501 PetscCall(ISRestoreIndices(ism,&rows)); 1502 PetscCall(ISRestoreIndices(isn,&cols)); 1503 PetscFunctionReturn(0); 1504 } 1505 1506 /*@ 1507 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1508 values into a matrix 1509 1510 Not Collective 1511 1512 Input Parameters: 1513 + mat - the matrix 1514 . row - the (block) row to set 1515 - v - a logically two-dimensional array of values 1516 1517 Notes: 1518 By the values, v, are column-oriented (for the block version) and sorted 1519 1520 All the nonzeros in the row must be provided 1521 1522 The matrix must have previously had its column indices set 1523 1524 The row must belong to this process 1525 1526 Level: intermediate 1527 1528 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1529 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`, `MatSetValuesRow()`, `MatSetLocalToGlobalMapping()` 1530 @*/ 1531 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1532 { 1533 PetscInt globalrow; 1534 1535 PetscFunctionBegin; 1536 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1537 PetscValidType(mat,1); 1538 PetscValidScalarPointer(v,3); 1539 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow)); 1540 PetscCall(MatSetValuesRow(mat,globalrow,v)); 1541 PetscFunctionReturn(0); 1542 } 1543 1544 /*@ 1545 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1546 values into a matrix 1547 1548 Not Collective 1549 1550 Input Parameters: 1551 + mat - the matrix 1552 . row - the (block) row to set 1553 - v - a logically two-dimensional (column major) array of values for block matrices with blocksize larger than one, otherwise a one dimensional array of values 1554 1555 Notes: 1556 The values, v, are column-oriented for the block version. 1557 1558 All the nonzeros in the row must be provided 1559 1560 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1561 1562 The row must belong to this process 1563 1564 Level: advanced 1565 1566 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1567 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1568 @*/ 1569 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1570 { 1571 PetscFunctionBeginHot; 1572 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1573 PetscValidType(mat,1); 1574 MatCheckPreallocated(mat,1); 1575 PetscValidScalarPointer(v,3); 1576 PetscCheck(mat->insertmode != ADD_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1577 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1578 mat->insertmode = INSERT_VALUES; 1579 1580 if (mat->assembled) { 1581 mat->was_assembled = PETSC_TRUE; 1582 mat->assembled = PETSC_FALSE; 1583 } 1584 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1585 PetscCheck(mat->ops->setvaluesrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1586 PetscCall((*mat->ops->setvaluesrow)(mat,row,v)); 1587 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1588 PetscFunctionReturn(0); 1589 } 1590 1591 /*@ 1592 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1593 Using structured grid indexing 1594 1595 Not Collective 1596 1597 Input Parameters: 1598 + mat - the matrix 1599 . m - number of rows being entered 1600 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1601 . n - number of columns being entered 1602 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1603 . v - a logically two-dimensional array of values 1604 - addv - either ADD_VALUES or INSERT_VALUES, where 1605 ADD_VALUES adds values to any existing entries, and 1606 INSERT_VALUES replaces existing entries with new values 1607 1608 Notes: 1609 By default the values, v, are row-oriented. See MatSetOption() for other options. 1610 1611 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1612 options cannot be mixed without intervening calls to the assembly 1613 routines. 1614 1615 The grid coordinates are across the entire grid, not just the local portion 1616 1617 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1618 as well as in C. 1619 1620 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1621 1622 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1623 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1624 1625 The columns and rows in the stencil passed in MUST be contained within the 1626 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1627 if you create a DMDA with an overlap of one grid level and on a particular process its first 1628 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1629 first i index you can use in your column and row indices in MatSetStencil() is 5. 1630 1631 In Fortran idxm and idxn should be declared as 1632 $ MatStencil idxm(4,m),idxn(4,n) 1633 and the values inserted using 1634 $ idxm(MatStencil_i,1) = i 1635 $ idxm(MatStencil_j,1) = j 1636 $ idxm(MatStencil_k,1) = k 1637 $ idxm(MatStencil_c,1) = c 1638 etc 1639 1640 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1641 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1642 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1643 DM_BOUNDARY_PERIODIC boundary type. 1644 1645 For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have 1646 a single value per point) you can skip filling those indices. 1647 1648 Inspired by the structured grid interface to the HYPRE package 1649 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1650 1651 Efficiency Alert: 1652 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1653 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1654 1655 Level: beginner 1656 1657 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1658 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil` 1659 @*/ 1660 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1661 { 1662 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1663 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1664 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1665 1666 PetscFunctionBegin; 1667 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1668 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1669 PetscValidType(mat,1); 1670 PetscValidPointer(idxm,3); 1671 PetscValidPointer(idxn,5); 1672 1673 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1674 jdxm = buf; jdxn = buf+m; 1675 } else { 1676 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1677 jdxm = bufm; jdxn = bufn; 1678 } 1679 for (i=0; i<m; i++) { 1680 for (j=0; j<3-sdim; j++) dxm++; 1681 tmp = *dxm++ - starts[0]; 1682 for (j=0; j<dim-1; j++) { 1683 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1684 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1685 } 1686 if (mat->stencil.noc) dxm++; 1687 jdxm[i] = tmp; 1688 } 1689 for (i=0; i<n; i++) { 1690 for (j=0; j<3-sdim; j++) dxn++; 1691 tmp = *dxn++ - starts[0]; 1692 for (j=0; j<dim-1; j++) { 1693 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1694 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1695 } 1696 if (mat->stencil.noc) dxn++; 1697 jdxn[i] = tmp; 1698 } 1699 PetscCall(MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv)); 1700 PetscCall(PetscFree2(bufm,bufn)); 1701 PetscFunctionReturn(0); 1702 } 1703 1704 /*@ 1705 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1706 Using structured grid indexing 1707 1708 Not Collective 1709 1710 Input Parameters: 1711 + mat - the matrix 1712 . m - number of rows being entered 1713 . idxm - grid coordinates for matrix rows being entered 1714 . n - number of columns being entered 1715 . idxn - grid coordinates for matrix columns being entered 1716 . v - a logically two-dimensional array of values 1717 - addv - either ADD_VALUES or INSERT_VALUES, where 1718 ADD_VALUES adds values to any existing entries, and 1719 INSERT_VALUES replaces existing entries with new values 1720 1721 Notes: 1722 By default the values, v, are row-oriented and unsorted. 1723 See MatSetOption() for other options. 1724 1725 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1726 options cannot be mixed without intervening calls to the assembly 1727 routines. 1728 1729 The grid coordinates are across the entire grid, not just the local portion 1730 1731 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1732 as well as in C. 1733 1734 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1735 1736 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1737 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1738 1739 The columns and rows in the stencil passed in MUST be contained within the 1740 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1741 if you create a DMDA with an overlap of one grid level and on a particular process its first 1742 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1743 first i index you can use in your column and row indices in MatSetStencil() is 5. 1744 1745 In Fortran idxm and idxn should be declared as 1746 $ MatStencil idxm(4,m),idxn(4,n) 1747 and the values inserted using 1748 $ idxm(MatStencil_i,1) = i 1749 $ idxm(MatStencil_j,1) = j 1750 $ idxm(MatStencil_k,1) = k 1751 etc 1752 1753 Negative indices may be passed in idxm and idxn, these rows and columns are 1754 simply ignored. This allows easily inserting element stiffness matrices 1755 with homogeneous Dirchlet boundary conditions that you don't want represented 1756 in the matrix. 1757 1758 Inspired by the structured grid interface to the HYPRE package 1759 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1760 1761 Level: beginner 1762 1763 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1764 `MatSetValues()`, `MatSetValuesStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil`, 1765 `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()` 1766 @*/ 1767 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1768 { 1769 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1770 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1771 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1772 1773 PetscFunctionBegin; 1774 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1775 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1776 PetscValidType(mat,1); 1777 PetscValidPointer(idxm,3); 1778 PetscValidPointer(idxn,5); 1779 PetscValidScalarPointer(v,6); 1780 1781 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1782 jdxm = buf; jdxn = buf+m; 1783 } else { 1784 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1785 jdxm = bufm; jdxn = bufn; 1786 } 1787 for (i=0; i<m; i++) { 1788 for (j=0; j<3-sdim; j++) dxm++; 1789 tmp = *dxm++ - starts[0]; 1790 for (j=0; j<sdim-1; j++) { 1791 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1792 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1793 } 1794 dxm++; 1795 jdxm[i] = tmp; 1796 } 1797 for (i=0; i<n; i++) { 1798 for (j=0; j<3-sdim; j++) dxn++; 1799 tmp = *dxn++ - starts[0]; 1800 for (j=0; j<sdim-1; j++) { 1801 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1802 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1803 } 1804 dxn++; 1805 jdxn[i] = tmp; 1806 } 1807 PetscCall(MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv)); 1808 PetscCall(PetscFree2(bufm,bufn)); 1809 PetscFunctionReturn(0); 1810 } 1811 1812 /*@ 1813 MatSetStencil - Sets the grid information for setting values into a matrix via 1814 MatSetValuesStencil() 1815 1816 Not Collective 1817 1818 Input Parameters: 1819 + mat - the matrix 1820 . dim - dimension of the grid 1, 2, or 3 1821 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1822 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1823 - dof - number of degrees of freedom per node 1824 1825 Inspired by the structured grid interface to the HYPRE package 1826 (www.llnl.gov/CASC/hyper) 1827 1828 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1829 user. 1830 1831 Level: beginner 1832 1833 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1834 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetValuesStencil()` 1835 @*/ 1836 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1837 { 1838 PetscFunctionBegin; 1839 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1840 PetscValidIntPointer(dims,3); 1841 PetscValidIntPointer(starts,4); 1842 1843 mat->stencil.dim = dim + (dof > 1); 1844 for (PetscInt i=0; i<dim; i++) { 1845 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1846 mat->stencil.starts[i] = starts[dim-i-1]; 1847 } 1848 mat->stencil.dims[dim] = dof; 1849 mat->stencil.starts[dim] = 0; 1850 mat->stencil.noc = (PetscBool)(dof == 1); 1851 PetscFunctionReturn(0); 1852 } 1853 1854 /*@C 1855 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1856 1857 Not Collective 1858 1859 Input Parameters: 1860 + mat - the matrix 1861 . v - a logically two-dimensional array of values 1862 . m, idxm - the number of block rows and their global block indices 1863 . n, idxn - the number of block columns and their global block indices 1864 - addv - either ADD_VALUES or INSERT_VALUES, where 1865 ADD_VALUES adds values to any existing entries, and 1866 INSERT_VALUES replaces existing entries with new values 1867 1868 Notes: 1869 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1870 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1871 1872 The m and n count the NUMBER of blocks in the row direction and column direction, 1873 NOT the total number of rows/columns; for example, if the block size is 2 and 1874 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1875 The values in idxm would be 1 2; that is the first index for each block divided by 1876 the block size. 1877 1878 Note that you must call MatSetBlockSize() when constructing this matrix (before 1879 preallocating it). 1880 1881 By default the values, v, are row-oriented, so the layout of 1882 v is the same as for MatSetValues(). See MatSetOption() for other options. 1883 1884 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1885 options cannot be mixed without intervening calls to the assembly 1886 routines. 1887 1888 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1889 as well as in C. 1890 1891 Negative indices may be passed in idxm and idxn, these rows and columns are 1892 simply ignored. This allows easily inserting element stiffness matrices 1893 with homogeneous Dirchlet boundary conditions that you don't want represented 1894 in the matrix. 1895 1896 Each time an entry is set within a sparse matrix via MatSetValues(), 1897 internal searching must be done to determine where to place the 1898 data in the matrix storage space. By instead inserting blocks of 1899 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1900 reduced. 1901 1902 Example: 1903 $ Suppose m=n=2 and block size(bs) = 2 The array is 1904 $ 1905 $ 1 2 | 3 4 1906 $ 5 6 | 7 8 1907 $ - - - | - - - 1908 $ 9 10 | 11 12 1909 $ 13 14 | 15 16 1910 $ 1911 $ v[] should be passed in like 1912 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1913 $ 1914 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1915 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1916 1917 Level: intermediate 1918 1919 .seealso: `MatSetBlockSize()`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesBlockedLocal()` 1920 @*/ 1921 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1922 { 1923 PetscFunctionBeginHot; 1924 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1925 PetscValidType(mat,1); 1926 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1927 PetscValidIntPointer(idxm,3); 1928 PetscValidIntPointer(idxn,5); 1929 MatCheckPreallocated(mat,1); 1930 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1931 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1932 if (PetscDefined(USE_DEBUG)) { 1933 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1934 PetscCheck(mat->ops->setvaluesblocked || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1935 } 1936 if (PetscDefined(USE_DEBUG)) { 1937 PetscInt rbs,cbs,M,N,i; 1938 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1939 PetscCall(MatGetSize(mat,&M,&N)); 1940 for (i=0; i<m; i++) PetscCheck(idxm[i]*rbs < M,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row block index %" PetscInt_FMT " (index %" PetscInt_FMT ") greater than row length %" PetscInt_FMT,i,idxm[i],M); 1941 for (i=0; i<n; i++) PetscCheck(idxn[i]*cbs < N,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column block index %" PetscInt_FMT " (index %" PetscInt_FMT ") great than column length %" PetscInt_FMT,i,idxn[i],N); 1942 } 1943 if (mat->assembled) { 1944 mat->was_assembled = PETSC_TRUE; 1945 mat->assembled = PETSC_FALSE; 1946 } 1947 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1948 if (mat->ops->setvaluesblocked) { 1949 PetscCall((*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv)); 1950 } else { 1951 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*iidxm,*iidxn; 1952 PetscInt i,j,bs,cbs; 1953 1954 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 1955 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1956 iidxm = buf; 1957 iidxn = buf + m*bs; 1958 } else { 1959 PetscCall(PetscMalloc2(m*bs,&bufr,n*cbs,&bufc)); 1960 iidxm = bufr; 1961 iidxn = bufc; 1962 } 1963 for (i=0; i<m; i++) { 1964 for (j=0; j<bs; j++) { 1965 iidxm[i*bs+j] = bs*idxm[i] + j; 1966 } 1967 } 1968 if (m != n || bs != cbs || idxm != idxn) { 1969 for (i=0; i<n; i++) { 1970 for (j=0; j<cbs; j++) { 1971 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1972 } 1973 } 1974 } else iidxn = iidxm; 1975 PetscCall(MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv)); 1976 PetscCall(PetscFree2(bufr,bufc)); 1977 } 1978 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1979 PetscFunctionReturn(0); 1980 } 1981 1982 /*@C 1983 MatGetValues - Gets a block of values from a matrix. 1984 1985 Not Collective; can only return values that are owned by the give process 1986 1987 Input Parameters: 1988 + mat - the matrix 1989 . v - a logically two-dimensional array for storing the values 1990 . m, idxm - the number of rows and their global indices 1991 - n, idxn - the number of columns and their global indices 1992 1993 Notes: 1994 The user must allocate space (m*n PetscScalars) for the values, v. 1995 The values, v, are then returned in a row-oriented format, 1996 analogous to that used by default in MatSetValues(). 1997 1998 MatGetValues() uses 0-based row and column numbers in 1999 Fortran as well as in C. 2000 2001 MatGetValues() requires that the matrix has been assembled 2002 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 2003 MatSetValues() and MatGetValues() CANNOT be made in succession 2004 without intermediate matrix assembly. 2005 2006 Negative row or column indices will be ignored and those locations in v[] will be 2007 left unchanged. 2008 2009 For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank. 2010 That is, rows with global index greater than or equal to rstart and less than rend where rstart and rend are obtainable 2011 from MatGetOwnershipRange(mat,&rstart,&rend). 2012 2013 Level: advanced 2014 2015 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatSetValues()`, `MatGetOwnershipRange()`, `MatGetValuesLocal()`, `MatGetValue()` 2016 @*/ 2017 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 2018 { 2019 PetscFunctionBegin; 2020 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2021 PetscValidType(mat,1); 2022 if (!m || !n) PetscFunctionReturn(0); 2023 PetscValidIntPointer(idxm,3); 2024 PetscValidIntPointer(idxn,5); 2025 PetscValidScalarPointer(v,6); 2026 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2027 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2028 PetscCheck(mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2029 MatCheckPreallocated(mat,1); 2030 2031 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2032 PetscCall((*mat->ops->getvalues)(mat,m,idxm,n,idxn,v)); 2033 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2034 PetscFunctionReturn(0); 2035 } 2036 2037 /*@C 2038 MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices 2039 defined previously by MatSetLocalToGlobalMapping() 2040 2041 Not Collective 2042 2043 Input Parameters: 2044 + mat - the matrix 2045 . nrow, irow - number of rows and their local indices 2046 - ncol, icol - number of columns and their local indices 2047 2048 Output Parameter: 2049 . y - a logically two-dimensional array of values 2050 2051 Notes: 2052 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine. 2053 2054 This routine can only return values that are owned by the requesting MPI rank. That is, for standard matrix formats, rows that, in the global numbering, 2055 are greater than or equal to rstart and less than rend where rstart and rend are obtainable from MatGetOwnershipRange(mat,&rstart,&rend). One can 2056 determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the ISLocalToGlobalMapping set 2057 with MatSetLocalToGlobalMapping(). 2058 2059 Developer Notes: 2060 This is labelled with C so does not automatically generate Fortran stubs and interfaces 2061 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2062 2063 Level: advanced 2064 2065 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2066 `MatSetValuesLocal()`, `MatGetValues()` 2067 @*/ 2068 PetscErrorCode MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[]) 2069 { 2070 PetscFunctionBeginHot; 2071 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2072 PetscValidType(mat,1); 2073 MatCheckPreallocated(mat,1); 2074 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */ 2075 PetscValidIntPointer(irow,3); 2076 PetscValidIntPointer(icol,5); 2077 if (PetscDefined(USE_DEBUG)) { 2078 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2079 PetscCheck(mat->ops->getvalueslocal || mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2080 } 2081 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2082 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2083 if (mat->ops->getvalueslocal) { 2084 PetscCall((*mat->ops->getvalueslocal)(mat,nrow,irow,ncol,icol,y)); 2085 } else { 2086 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm; 2087 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2088 irowm = buf; icolm = buf+nrow; 2089 } else { 2090 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2091 irowm = bufr; icolm = bufc; 2092 } 2093 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping())."); 2094 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping())."); 2095 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm)); 2096 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm)); 2097 PetscCall(MatGetValues(mat,nrow,irowm,ncol,icolm,y)); 2098 PetscCall(PetscFree2(bufr,bufc)); 2099 } 2100 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2101 PetscFunctionReturn(0); 2102 } 2103 2104 /*@ 2105 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 2106 the same size. Currently, this can only be called once and creates the given matrix. 2107 2108 Not Collective 2109 2110 Input Parameters: 2111 + mat - the matrix 2112 . nb - the number of blocks 2113 . bs - the number of rows (and columns) in each block 2114 . rows - a concatenation of the rows for each block 2115 - v - a concatenation of logically two-dimensional arrays of values 2116 2117 Notes: 2118 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 2119 2120 Level: advanced 2121 2122 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 2123 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 2124 @*/ 2125 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 2126 { 2127 PetscFunctionBegin; 2128 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2129 PetscValidType(mat,1); 2130 PetscValidIntPointer(rows,4); 2131 PetscValidScalarPointer(v,5); 2132 PetscAssert(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2133 2134 PetscCall(PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0)); 2135 if (mat->ops->setvaluesbatch) { 2136 PetscCall((*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v)); 2137 } else { 2138 for (PetscInt b = 0; b < nb; ++b) PetscCall(MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES)); 2139 } 2140 PetscCall(PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0)); 2141 PetscFunctionReturn(0); 2142 } 2143 2144 /*@ 2145 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2146 the routine MatSetValuesLocal() to allow users to insert matrix entries 2147 using a local (per-processor) numbering. 2148 2149 Not Collective 2150 2151 Input Parameters: 2152 + x - the matrix 2153 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2154 - cmapping - column mapping 2155 2156 Level: intermediate 2157 2158 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesLocal()`, `MatGetValuesLocal()` 2159 @*/ 2160 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2161 { 2162 PetscFunctionBegin; 2163 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2164 PetscValidType(x,1); 2165 if (rmapping) PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2166 if (cmapping) PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2167 if (x->ops->setlocaltoglobalmapping) { 2168 PetscCall((*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping)); 2169 } else { 2170 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping)); 2171 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping)); 2172 } 2173 PetscFunctionReturn(0); 2174 } 2175 2176 /*@ 2177 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2178 2179 Not Collective 2180 2181 Input Parameter: 2182 . A - the matrix 2183 2184 Output Parameters: 2185 + rmapping - row mapping 2186 - cmapping - column mapping 2187 2188 Level: advanced 2189 2190 .seealso: `MatSetValuesLocal()` 2191 @*/ 2192 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2193 { 2194 PetscFunctionBegin; 2195 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2196 PetscValidType(A,1); 2197 if (rmapping) { 2198 PetscValidPointer(rmapping,2); 2199 *rmapping = A->rmap->mapping; 2200 } 2201 if (cmapping) { 2202 PetscValidPointer(cmapping,3); 2203 *cmapping = A->cmap->mapping; 2204 } 2205 PetscFunctionReturn(0); 2206 } 2207 2208 /*@ 2209 MatSetLayouts - Sets the PetscLayout objects for rows and columns of a matrix 2210 2211 Logically Collective on A 2212 2213 Input Parameters: 2214 + A - the matrix 2215 . rmap - row layout 2216 - cmap - column layout 2217 2218 Level: advanced 2219 2220 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatGetLayouts()` 2221 @*/ 2222 PetscErrorCode MatSetLayouts(Mat A,PetscLayout rmap,PetscLayout cmap) 2223 { 2224 PetscFunctionBegin; 2225 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2226 PetscCall(PetscLayoutReference(rmap,&A->rmap)); 2227 PetscCall(PetscLayoutReference(cmap,&A->cmap)); 2228 PetscFunctionReturn(0); 2229 } 2230 2231 /*@ 2232 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2233 2234 Not Collective 2235 2236 Input Parameter: 2237 . A - the matrix 2238 2239 Output Parameters: 2240 + rmap - row layout 2241 - cmap - column layout 2242 2243 Level: advanced 2244 2245 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatSetLayouts()` 2246 @*/ 2247 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2248 { 2249 PetscFunctionBegin; 2250 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2251 PetscValidType(A,1); 2252 if (rmap) { 2253 PetscValidPointer(rmap,2); 2254 *rmap = A->rmap; 2255 } 2256 if (cmap) { 2257 PetscValidPointer(cmap,3); 2258 *cmap = A->cmap; 2259 } 2260 PetscFunctionReturn(0); 2261 } 2262 2263 /*@C 2264 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2265 using a local numbering of the nodes. 2266 2267 Not Collective 2268 2269 Input Parameters: 2270 + mat - the matrix 2271 . nrow, irow - number of rows and their local indices 2272 . ncol, icol - number of columns and their local indices 2273 . y - a logically two-dimensional array of values 2274 - addv - either INSERT_VALUES or ADD_VALUES, where 2275 ADD_VALUES adds values to any existing entries, and 2276 INSERT_VALUES replaces existing entries with new values 2277 2278 Notes: 2279 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2280 MatSetUp() before using this routine 2281 2282 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2283 2284 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2285 options cannot be mixed without intervening calls to the assembly 2286 routines. 2287 2288 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2289 MUST be called after all calls to MatSetValuesLocal() have been completed. 2290 2291 Level: intermediate 2292 2293 Developer Notes: 2294 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2295 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2296 2297 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2298 `MatSetValueLocal()`, `MatGetValuesLocal()` 2299 @*/ 2300 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2301 { 2302 PetscFunctionBeginHot; 2303 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2304 PetscValidType(mat,1); 2305 MatCheckPreallocated(mat,1); 2306 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2307 PetscValidIntPointer(irow,3); 2308 PetscValidIntPointer(icol,5); 2309 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2310 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2311 if (PetscDefined(USE_DEBUG)) { 2312 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2313 PetscCheck(mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2314 } 2315 2316 if (mat->assembled) { 2317 mat->was_assembled = PETSC_TRUE; 2318 mat->assembled = PETSC_FALSE; 2319 } 2320 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2321 if (mat->ops->setvalueslocal) { 2322 PetscCall((*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv)); 2323 } else { 2324 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2325 const PetscInt *irowm,*icolm; 2326 2327 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2328 bufr = buf; 2329 bufc = buf + nrow; 2330 irowm = bufr; 2331 icolm = bufc; 2332 } else { 2333 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2334 irowm = bufr; 2335 icolm = bufc; 2336 } 2337 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,bufr)); 2338 else irowm = irow; 2339 if (mat->cmap->mapping) { 2340 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2341 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,bufc)); 2342 } else icolm = irowm; 2343 } else icolm = icol; 2344 PetscCall(MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv)); 2345 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2346 } 2347 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2348 PetscFunctionReturn(0); 2349 } 2350 2351 /*@C 2352 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2353 using a local ordering of the nodes a block at a time. 2354 2355 Not Collective 2356 2357 Input Parameters: 2358 + x - the matrix 2359 . nrow, irow - number of rows and their local indices 2360 . ncol, icol - number of columns and their local indices 2361 . y - a logically two-dimensional array of values 2362 - addv - either INSERT_VALUES or ADD_VALUES, where 2363 ADD_VALUES adds values to any existing entries, and 2364 INSERT_VALUES replaces existing entries with new values 2365 2366 Notes: 2367 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2368 MatSetUp() before using this routine 2369 2370 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2371 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2372 2373 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2374 options cannot be mixed without intervening calls to the assembly 2375 routines. 2376 2377 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2378 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2379 2380 Level: intermediate 2381 2382 Developer Notes: 2383 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2384 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2385 2386 .seealso: `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, 2387 `MatSetValuesLocal()`, `MatSetValuesBlocked()` 2388 @*/ 2389 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2390 { 2391 PetscFunctionBeginHot; 2392 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2393 PetscValidType(mat,1); 2394 MatCheckPreallocated(mat,1); 2395 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2396 PetscValidIntPointer(irow,3); 2397 PetscValidIntPointer(icol,5); 2398 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2399 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2400 if (PetscDefined(USE_DEBUG)) { 2401 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2402 PetscCheck(mat->ops->setvaluesblockedlocal || mat->ops->setvaluesblocked || mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2403 } 2404 2405 if (mat->assembled) { 2406 mat->was_assembled = PETSC_TRUE; 2407 mat->assembled = PETSC_FALSE; 2408 } 2409 if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2410 PetscInt irbs, rbs; 2411 PetscCall(MatGetBlockSizes(mat, &rbs, NULL)); 2412 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs)); 2413 PetscCheck(rbs == irbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %" PetscInt_FMT ", row l2g map %" PetscInt_FMT,rbs,irbs); 2414 } 2415 if (PetscUnlikelyDebug(mat->cmap->mapping)) { 2416 PetscInt icbs, cbs; 2417 PetscCall(MatGetBlockSizes(mat,NULL,&cbs)); 2418 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs)); 2419 PetscCheck(cbs == icbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %" PetscInt_FMT ", col l2g map %" PetscInt_FMT,cbs,icbs); 2420 } 2421 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2422 if (mat->ops->setvaluesblockedlocal) { 2423 PetscCall((*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv)); 2424 } else { 2425 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2426 const PetscInt *irowm,*icolm; 2427 2428 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2429 bufr = buf; 2430 bufc = buf + nrow; 2431 irowm = bufr; 2432 icolm = bufc; 2433 } else { 2434 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2435 irowm = bufr; 2436 icolm = bufc; 2437 } 2438 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,bufr)); 2439 else irowm = irow; 2440 if (mat->cmap->mapping) { 2441 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2442 PetscCall(ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,bufc)); 2443 } else icolm = irowm; 2444 } else icolm = icol; 2445 PetscCall(MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv)); 2446 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2447 } 2448 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2449 PetscFunctionReturn(0); 2450 } 2451 2452 /*@ 2453 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2454 2455 Collective on Mat 2456 2457 Input Parameters: 2458 + mat - the matrix 2459 - x - the vector to be multiplied 2460 2461 Output Parameters: 2462 . y - the result 2463 2464 Notes: 2465 The vectors x and y cannot be the same. I.e., one cannot 2466 call MatMult(A,y,y). 2467 2468 Level: developer 2469 2470 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2471 @*/ 2472 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2473 { 2474 PetscFunctionBegin; 2475 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2476 PetscValidType(mat,1); 2477 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2478 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2479 2480 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2481 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2482 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2483 MatCheckPreallocated(mat,1); 2484 2485 PetscCheck(mat->ops->multdiagonalblock,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2486 PetscCall((*mat->ops->multdiagonalblock)(mat,x,y)); 2487 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2488 PetscFunctionReturn(0); 2489 } 2490 2491 /* --------------------------------------------------------*/ 2492 /*@ 2493 MatMult - Computes the matrix-vector product, y = Ax. 2494 2495 Neighbor-wise Collective on Mat 2496 2497 Input Parameters: 2498 + mat - the matrix 2499 - x - the vector to be multiplied 2500 2501 Output Parameters: 2502 . y - the result 2503 2504 Notes: 2505 The vectors x and y cannot be the same. I.e., one cannot 2506 call MatMult(A,y,y). 2507 2508 Level: beginner 2509 2510 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2511 @*/ 2512 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2513 { 2514 PetscFunctionBegin; 2515 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2516 PetscValidType(mat,1); 2517 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2518 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2519 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2520 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2521 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2522 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 2523 PetscCheck(mat->rmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N); 2524 PetscCheck(mat->cmap->n == x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,x->map->n); 2525 PetscCheck(mat->rmap->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,y->map->n); 2526 PetscCall(VecSetErrorIfLocked(y,3)); 2527 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2528 MatCheckPreallocated(mat,1); 2529 2530 PetscCall(VecLockReadPush(x)); 2531 PetscCheck(mat->ops->mult,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2532 PetscCall(PetscLogEventBegin(MAT_Mult,mat,x,y,0)); 2533 PetscCall((*mat->ops->mult)(mat,x,y)); 2534 PetscCall(PetscLogEventEnd(MAT_Mult,mat,x,y,0)); 2535 if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE)); 2536 PetscCall(VecLockReadPop(x)); 2537 PetscFunctionReturn(0); 2538 } 2539 2540 /*@ 2541 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2542 2543 Neighbor-wise Collective on Mat 2544 2545 Input Parameters: 2546 + mat - the matrix 2547 - x - the vector to be multiplied 2548 2549 Output Parameters: 2550 . y - the result 2551 2552 Notes: 2553 The vectors x and y cannot be the same. I.e., one cannot 2554 call MatMultTranspose(A,y,y). 2555 2556 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2557 use MatMultHermitianTranspose() 2558 2559 Level: beginner 2560 2561 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultTransposeAdd()`, `MatMultHermitianTranspose()`, `MatTranspose()` 2562 @*/ 2563 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2564 { 2565 PetscErrorCode (*op)(Mat,Vec,Vec) = NULL; 2566 2567 PetscFunctionBegin; 2568 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2569 PetscValidType(mat,1); 2570 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2571 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2572 2573 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2574 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2575 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2576 PetscCheck(mat->cmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 2577 PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 2578 PetscCheck(mat->cmap->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,y->map->n); 2579 PetscCheck(mat->rmap->n == x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,x->map->n); 2580 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2581 MatCheckPreallocated(mat,1); 2582 2583 if (!mat->ops->multtranspose) { 2584 if (mat->symmetric == PETSC_BOOL3_TRUE && mat->ops->mult) op = mat->ops->mult; 2585 PetscCheck(op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply transpose defined or is symmetric and does not have a multiply defined",((PetscObject)mat)->type_name); 2586 } else op = mat->ops->multtranspose; 2587 PetscCall(PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0)); 2588 PetscCall(VecLockReadPush(x)); 2589 PetscCall((*op)(mat,x,y)); 2590 PetscCall(VecLockReadPop(x)); 2591 PetscCall(PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0)); 2592 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2593 if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE)); 2594 PetscFunctionReturn(0); 2595 } 2596 2597 /*@ 2598 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2599 2600 Neighbor-wise Collective on Mat 2601 2602 Input Parameters: 2603 + mat - the matrix 2604 - x - the vector to be multilplied 2605 2606 Output Parameters: 2607 . y - the result 2608 2609 Notes: 2610 The vectors x and y cannot be the same. I.e., one cannot 2611 call MatMultHermitianTranspose(A,y,y). 2612 2613 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2614 2615 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2616 2617 Level: beginner 2618 2619 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultHermitianTransposeAdd()`, `MatMultTranspose()` 2620 @*/ 2621 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2622 { 2623 PetscFunctionBegin; 2624 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2625 PetscValidType(mat,1); 2626 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2627 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2628 2629 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2630 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2631 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2632 PetscCheck(mat->cmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 2633 PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 2634 PetscCheck(mat->cmap->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,y->map->n); 2635 PetscCheck(mat->rmap->n == x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,x->map->n); 2636 MatCheckPreallocated(mat,1); 2637 2638 PetscCall(PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0)); 2639 #if defined(PETSC_USE_COMPLEX) 2640 if (mat->ops->multhermitiantranspose || (mat->hermitian == PETSC_BOOL3_TRUE && mat->ops->mult)) { 2641 PetscCall(VecLockReadPush(x)); 2642 if (mat->ops->multhermitiantranspose) { 2643 PetscCall((*mat->ops->multhermitiantranspose)(mat,x,y)); 2644 } else { 2645 PetscCall((*mat->ops->mult)(mat,x,y)); 2646 } 2647 PetscCall(VecLockReadPop(x)); 2648 } else { 2649 Vec w; 2650 PetscCall(VecDuplicate(x,&w)); 2651 PetscCall(VecCopy(x,w)); 2652 PetscCall(VecConjugate(w)); 2653 PetscCall(MatMultTranspose(mat,w,y)); 2654 PetscCall(VecDestroy(&w)); 2655 PetscCall(VecConjugate(y)); 2656 } 2657 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2658 #else 2659 PetscCall(MatMultTranspose(mat,x,y)); 2660 #endif 2661 PetscCall(PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0)); 2662 PetscFunctionReturn(0); 2663 } 2664 2665 /*@ 2666 MatMultAdd - Computes v3 = v2 + A * v1. 2667 2668 Neighbor-wise Collective on Mat 2669 2670 Input Parameters: 2671 + mat - the matrix 2672 - v1, v2 - the vectors 2673 2674 Output Parameters: 2675 . v3 - the result 2676 2677 Notes: 2678 The vectors v1 and v3 cannot be the same. I.e., one cannot 2679 call MatMultAdd(A,v1,v2,v1). 2680 2681 Level: beginner 2682 2683 .seealso: `MatMultTranspose()`, `MatMult()`, `MatMultTransposeAdd()` 2684 @*/ 2685 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2686 { 2687 PetscFunctionBegin; 2688 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2689 PetscValidType(mat,1); 2690 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2691 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2692 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2693 2694 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2695 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2696 PetscCheck(mat->cmap->N == v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v1->map->N); 2697 /* PetscCheck(mat->rmap->N == v2->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v2->map->N); 2698 PetscCheck(mat->rmap->N == v3->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v3->map->N); */ 2699 PetscCheck(mat->rmap->n == v3->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,v3->map->n); 2700 PetscCheck(mat->rmap->n == v2->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,v2->map->n); 2701 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2702 MatCheckPreallocated(mat,1); 2703 2704 PetscCheck(mat->ops->multadd,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type %s",((PetscObject)mat)->type_name); 2705 PetscCall(PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3)); 2706 PetscCall(VecLockReadPush(v1)); 2707 PetscCall((*mat->ops->multadd)(mat,v1,v2,v3)); 2708 PetscCall(VecLockReadPop(v1)); 2709 PetscCall(PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3)); 2710 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2711 PetscFunctionReturn(0); 2712 } 2713 2714 /*@ 2715 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2716 2717 Neighbor-wise Collective on Mat 2718 2719 Input Parameters: 2720 + mat - the matrix 2721 - v1, v2 - the vectors 2722 2723 Output Parameters: 2724 . v3 - the result 2725 2726 Notes: 2727 The vectors v1 and v3 cannot be the same. I.e., one cannot 2728 call MatMultTransposeAdd(A,v1,v2,v1). 2729 2730 Level: beginner 2731 2732 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2733 @*/ 2734 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2735 { 2736 PetscErrorCode (*op)(Mat,Vec,Vec,Vec) = (!mat->ops->multtransposeadd && mat->symmetric) ? mat->ops->multadd : mat->ops->multtransposeadd; 2737 2738 PetscFunctionBegin; 2739 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2740 PetscValidType(mat,1); 2741 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2742 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2743 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2744 2745 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2746 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2747 PetscCheck(mat->rmap->N == v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v1->map->N); 2748 PetscCheck(mat->cmap->N == v2->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v2->map->N); 2749 PetscCheck(mat->cmap->N == v3->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v3->map->N); 2750 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2751 PetscCheck(op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2752 MatCheckPreallocated(mat,1); 2753 2754 PetscCall(PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2755 PetscCall(VecLockReadPush(v1)); 2756 PetscCall((*op)(mat,v1,v2,v3)); 2757 PetscCall(VecLockReadPop(v1)); 2758 PetscCall(PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2759 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2760 PetscFunctionReturn(0); 2761 } 2762 2763 /*@ 2764 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2765 2766 Neighbor-wise Collective on Mat 2767 2768 Input Parameters: 2769 + mat - the matrix 2770 - v1, v2 - the vectors 2771 2772 Output Parameters: 2773 . v3 - the result 2774 2775 Notes: 2776 The vectors v1 and v3 cannot be the same. I.e., one cannot 2777 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2778 2779 Level: beginner 2780 2781 .seealso: `MatMultHermitianTranspose()`, `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2782 @*/ 2783 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2784 { 2785 PetscFunctionBegin; 2786 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2787 PetscValidType(mat,1); 2788 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2789 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2790 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2791 2792 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2793 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2794 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2795 PetscCheck(mat->rmap->N == v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v1->map->N); 2796 PetscCheck(mat->cmap->N == v2->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v2->map->N); 2797 PetscCheck(mat->cmap->N == v3->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v3->map->N); 2798 MatCheckPreallocated(mat,1); 2799 2800 PetscCall(PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2801 PetscCall(VecLockReadPush(v1)); 2802 if (mat->ops->multhermitiantransposeadd) { 2803 PetscCall((*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3)); 2804 } else { 2805 Vec w,z; 2806 PetscCall(VecDuplicate(v1,&w)); 2807 PetscCall(VecCopy(v1,w)); 2808 PetscCall(VecConjugate(w)); 2809 PetscCall(VecDuplicate(v3,&z)); 2810 PetscCall(MatMultTranspose(mat,w,z)); 2811 PetscCall(VecDestroy(&w)); 2812 PetscCall(VecConjugate(z)); 2813 if (v2 != v3) { 2814 PetscCall(VecWAXPY(v3,1.0,v2,z)); 2815 } else { 2816 PetscCall(VecAXPY(v3,1.0,z)); 2817 } 2818 PetscCall(VecDestroy(&z)); 2819 } 2820 PetscCall(VecLockReadPop(v1)); 2821 PetscCall(PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2822 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2823 PetscFunctionReturn(0); 2824 } 2825 2826 /*@C 2827 MatGetFactorType - gets the type of factorization it is 2828 2829 Not Collective 2830 2831 Input Parameters: 2832 . mat - the matrix 2833 2834 Output Parameters: 2835 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2836 2837 Level: intermediate 2838 2839 .seealso: `MatFactorType`, `MatGetFactor()`, `MatSetFactorType()` 2840 @*/ 2841 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2842 { 2843 PetscFunctionBegin; 2844 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2845 PetscValidType(mat,1); 2846 PetscValidPointer(t,2); 2847 *t = mat->factortype; 2848 PetscFunctionReturn(0); 2849 } 2850 2851 /*@C 2852 MatSetFactorType - sets the type of factorization it is 2853 2854 Logically Collective on Mat 2855 2856 Input Parameters: 2857 + mat - the matrix 2858 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2859 2860 Level: intermediate 2861 2862 .seealso: `MatFactorType`, `MatGetFactor()`, `MatGetFactorType()` 2863 @*/ 2864 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2865 { 2866 PetscFunctionBegin; 2867 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2868 PetscValidType(mat,1); 2869 mat->factortype = t; 2870 PetscFunctionReturn(0); 2871 } 2872 2873 /* ------------------------------------------------------------*/ 2874 /*@C 2875 MatGetInfo - Returns information about matrix storage (number of 2876 nonzeros, memory, etc.). 2877 2878 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2879 2880 Input Parameter: 2881 . mat - the matrix 2882 2883 Output Parameters: 2884 + flag - flag indicating the type of parameters to be returned 2885 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2886 MAT_GLOBAL_SUM - sum over all processors) 2887 - info - matrix information context 2888 2889 Notes: 2890 The MatInfo context contains a variety of matrix data, including 2891 number of nonzeros allocated and used, number of mallocs during 2892 matrix assembly, etc. Additional information for factored matrices 2893 is provided (such as the fill ratio, number of mallocs during 2894 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2895 when using the runtime options 2896 $ -info -mat_view ::ascii_info 2897 2898 Example for C/C++ Users: 2899 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2900 data within the MatInfo context. For example, 2901 .vb 2902 MatInfo info; 2903 Mat A; 2904 double mal, nz_a, nz_u; 2905 2906 MatGetInfo(A,MAT_LOCAL,&info); 2907 mal = info.mallocs; 2908 nz_a = info.nz_allocated; 2909 .ve 2910 2911 Example for Fortran Users: 2912 Fortran users should declare info as a double precision 2913 array of dimension MAT_INFO_SIZE, and then extract the parameters 2914 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2915 a complete list of parameter names. 2916 .vb 2917 double precision info(MAT_INFO_SIZE) 2918 double precision mal, nz_a 2919 Mat A 2920 integer ierr 2921 2922 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2923 mal = info(MAT_INFO_MALLOCS) 2924 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2925 .ve 2926 2927 Level: intermediate 2928 2929 Developer Note: fortran interface is not autogenerated as the f90 2930 interface definition cannot be generated correctly [due to MatInfo] 2931 2932 .seealso: `MatStashGetInfo()` 2933 2934 @*/ 2935 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2936 { 2937 PetscFunctionBegin; 2938 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2939 PetscValidType(mat,1); 2940 PetscValidPointer(info,3); 2941 PetscCheck(mat->ops->getinfo,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2942 MatCheckPreallocated(mat,1); 2943 PetscCall((*mat->ops->getinfo)(mat,flag,info)); 2944 PetscFunctionReturn(0); 2945 } 2946 2947 /* 2948 This is used by external packages where it is not easy to get the info from the actual 2949 matrix factorization. 2950 */ 2951 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2952 { 2953 PetscFunctionBegin; 2954 PetscCall(PetscMemzero(info,sizeof(MatInfo))); 2955 PetscFunctionReturn(0); 2956 } 2957 2958 /* ----------------------------------------------------------*/ 2959 2960 /*@C 2961 MatLUFactor - Performs in-place LU factorization of matrix. 2962 2963 Collective on Mat 2964 2965 Input Parameters: 2966 + mat - the matrix 2967 . row - row permutation 2968 . col - column permutation 2969 - info - options for factorization, includes 2970 $ fill - expected fill as ratio of original fill. 2971 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2972 $ Run with the option -info to determine an optimal value to use 2973 2974 Notes: 2975 Most users should employ the simplified KSP interface for linear solvers 2976 instead of working directly with matrix algebra routines such as this. 2977 See, e.g., KSPCreate(). 2978 2979 This changes the state of the matrix to a factored matrix; it cannot be used 2980 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2981 2982 Level: developer 2983 2984 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, 2985 `MatGetOrdering()`, `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 2986 2987 Developer Note: fortran interface is not autogenerated as the f90 2988 interface definition cannot be generated correctly [due to MatFactorInfo] 2989 2990 @*/ 2991 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2992 { 2993 MatFactorInfo tinfo; 2994 2995 PetscFunctionBegin; 2996 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2997 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2998 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2999 if (info) PetscValidPointer(info,4); 3000 PetscValidType(mat,1); 3001 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3002 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3003 PetscCheck(mat->ops->lufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3004 MatCheckPreallocated(mat,1); 3005 if (!info) { 3006 PetscCall(MatFactorInfoInitialize(&tinfo)); 3007 info = &tinfo; 3008 } 3009 3010 PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,row,col,0)); 3011 PetscCall((*mat->ops->lufactor)(mat,row,col,info)); 3012 PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,row,col,0)); 3013 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3014 PetscFunctionReturn(0); 3015 } 3016 3017 /*@C 3018 MatILUFactor - Performs in-place ILU factorization of matrix. 3019 3020 Collective on Mat 3021 3022 Input Parameters: 3023 + mat - the matrix 3024 . row - row permutation 3025 . col - column permutation 3026 - info - structure containing 3027 $ levels - number of levels of fill. 3028 $ expected fill - as ratio of original fill. 3029 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 3030 missing diagonal entries) 3031 3032 Notes: 3033 Probably really in-place only when level of fill is zero, otherwise allocates 3034 new space to store factored matrix and deletes previous memory. 3035 3036 Most users should employ the simplified KSP interface for linear solvers 3037 instead of working directly with matrix algebra routines such as this. 3038 See, e.g., KSPCreate(). 3039 3040 Level: developer 3041 3042 .seealso: `MatILUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 3043 3044 Developer Note: fortran interface is not autogenerated as the f90 3045 interface definition cannot be generated correctly [due to MatFactorInfo] 3046 3047 @*/ 3048 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3049 { 3050 PetscFunctionBegin; 3051 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3052 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3053 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3054 PetscValidPointer(info,4); 3055 PetscValidType(mat,1); 3056 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 3057 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3058 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3059 PetscCheck(mat->ops->ilufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3060 MatCheckPreallocated(mat,1); 3061 3062 PetscCall(PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0)); 3063 PetscCall((*mat->ops->ilufactor)(mat,row,col,info)); 3064 PetscCall(PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0)); 3065 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3066 PetscFunctionReturn(0); 3067 } 3068 3069 /*@C 3070 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3071 Call this routine before calling MatLUFactorNumeric(). 3072 3073 Collective on Mat 3074 3075 Input Parameters: 3076 + fact - the factor matrix obtained with MatGetFactor() 3077 . mat - the matrix 3078 . row, col - row and column permutations 3079 - info - options for factorization, includes 3080 $ fill - expected fill as ratio of original fill. 3081 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3082 $ Run with the option -info to determine an optimal value to use 3083 3084 Notes: 3085 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3086 3087 Most users should employ the simplified KSP interface for linear solvers 3088 instead of working directly with matrix algebra routines such as this. 3089 See, e.g., KSPCreate(). 3090 3091 Level: developer 3092 3093 .seealso: `MatLUFactor()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3094 3095 Developer Note: fortran interface is not autogenerated as the f90 3096 interface definition cannot be generated correctly [due to MatFactorInfo] 3097 3098 @*/ 3099 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3100 { 3101 MatFactorInfo tinfo; 3102 3103 PetscFunctionBegin; 3104 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3105 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 3106 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 3107 if (info) PetscValidPointer(info,5); 3108 PetscValidType(mat,2); 3109 PetscValidPointer(fact,1); 3110 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3111 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3112 if (!(fact)->ops->lufactorsymbolic) { 3113 MatSolverType stype; 3114 PetscCall(MatFactorGetSolverType(fact,&stype)); 3115 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,stype); 3116 } 3117 MatCheckPreallocated(mat,2); 3118 if (!info) { 3119 PetscCall(MatFactorInfoInitialize(&tinfo)); 3120 info = &tinfo; 3121 } 3122 3123 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0)); 3124 PetscCall((fact->ops->lufactorsymbolic)(fact,mat,row,col,info)); 3125 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0)); 3126 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3127 PetscFunctionReturn(0); 3128 } 3129 3130 /*@C 3131 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3132 Call this routine after first calling MatLUFactorSymbolic(). 3133 3134 Collective on Mat 3135 3136 Input Parameters: 3137 + fact - the factor matrix obtained with MatGetFactor() 3138 . mat - the matrix 3139 - info - options for factorization 3140 3141 Notes: 3142 See MatLUFactor() for in-place factorization. See 3143 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3144 3145 Most users should employ the simplified KSP interface for linear solvers 3146 instead of working directly with matrix algebra routines such as this. 3147 See, e.g., KSPCreate(). 3148 3149 Level: developer 3150 3151 .seealso: `MatLUFactorSymbolic()`, `MatLUFactor()`, `MatCholeskyFactor()` 3152 3153 Developer Note: fortran interface is not autogenerated as the f90 3154 interface definition cannot be generated correctly [due to MatFactorInfo] 3155 3156 @*/ 3157 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3158 { 3159 MatFactorInfo tinfo; 3160 3161 PetscFunctionBegin; 3162 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3163 PetscValidType(mat,2); 3164 PetscValidPointer(fact,1); 3165 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3166 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3167 PetscCheck(mat->rmap->N == (fact)->rmap->N && mat->cmap->N == (fact)->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3168 3169 PetscCheck((fact)->ops->lufactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3170 MatCheckPreallocated(mat,2); 3171 if (!info) { 3172 PetscCall(MatFactorInfoInitialize(&tinfo)); 3173 info = &tinfo; 3174 } 3175 3176 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0)); 3177 else PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,fact,0,0)); 3178 PetscCall((fact->ops->lufactornumeric)(fact,mat,info)); 3179 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0)); 3180 else PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,fact,0,0)); 3181 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3182 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3183 PetscFunctionReturn(0); 3184 } 3185 3186 /*@C 3187 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3188 symmetric matrix. 3189 3190 Collective on Mat 3191 3192 Input Parameters: 3193 + mat - the matrix 3194 . perm - row and column permutations 3195 - f - expected fill as ratio of original fill 3196 3197 Notes: 3198 See MatLUFactor() for the nonsymmetric case. See also 3199 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3200 3201 Most users should employ the simplified KSP interface for linear solvers 3202 instead of working directly with matrix algebra routines such as this. 3203 See, e.g., KSPCreate(). 3204 3205 Level: developer 3206 3207 .seealso: `MatLUFactor()`, `MatCholeskyFactorSymbolic()`, `MatCholeskyFactorNumeric()` 3208 `MatGetOrdering()` 3209 3210 Developer Note: fortran interface is not autogenerated as the f90 3211 interface definition cannot be generated correctly [due to MatFactorInfo] 3212 3213 @*/ 3214 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3215 { 3216 MatFactorInfo tinfo; 3217 3218 PetscFunctionBegin; 3219 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3220 PetscValidType(mat,1); 3221 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3222 if (info) PetscValidPointer(info,3); 3223 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3224 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3225 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3226 PetscCheck(mat->ops->choleskyfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name); 3227 MatCheckPreallocated(mat,1); 3228 if (!info) { 3229 PetscCall(MatFactorInfoInitialize(&tinfo)); 3230 info = &tinfo; 3231 } 3232 3233 PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0)); 3234 PetscCall((*mat->ops->choleskyfactor)(mat,perm,info)); 3235 PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0)); 3236 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3237 PetscFunctionReturn(0); 3238 } 3239 3240 /*@C 3241 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3242 of a symmetric matrix. 3243 3244 Collective on Mat 3245 3246 Input Parameters: 3247 + fact - the factor matrix obtained with MatGetFactor() 3248 . mat - the matrix 3249 . perm - row and column permutations 3250 - info - options for factorization, includes 3251 $ fill - expected fill as ratio of original fill. 3252 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3253 $ Run with the option -info to determine an optimal value to use 3254 3255 Notes: 3256 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3257 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3258 3259 Most users should employ the simplified KSP interface for linear solvers 3260 instead of working directly with matrix algebra routines such as this. 3261 See, e.g., KSPCreate(). 3262 3263 Level: developer 3264 3265 .seealso: `MatLUFactorSymbolic()`, `MatCholeskyFactor()`, `MatCholeskyFactorNumeric()` 3266 `MatGetOrdering()` 3267 3268 Developer Note: fortran interface is not autogenerated as the f90 3269 interface definition cannot be generated correctly [due to MatFactorInfo] 3270 3271 @*/ 3272 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3273 { 3274 MatFactorInfo tinfo; 3275 3276 PetscFunctionBegin; 3277 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3278 PetscValidType(mat,2); 3279 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 3280 if (info) PetscValidPointer(info,4); 3281 PetscValidPointer(fact,1); 3282 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3283 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3284 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3285 if (!(fact)->ops->choleskyfactorsymbolic) { 3286 MatSolverType stype; 3287 PetscCall(MatFactorGetSolverType(fact,&stype)); 3288 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,stype); 3289 } 3290 MatCheckPreallocated(mat,2); 3291 if (!info) { 3292 PetscCall(MatFactorInfoInitialize(&tinfo)); 3293 info = &tinfo; 3294 } 3295 3296 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3297 PetscCall((fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info)); 3298 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3299 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3300 PetscFunctionReturn(0); 3301 } 3302 3303 /*@C 3304 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3305 of a symmetric matrix. Call this routine after first calling 3306 MatCholeskyFactorSymbolic(). 3307 3308 Collective on Mat 3309 3310 Input Parameters: 3311 + fact - the factor matrix obtained with MatGetFactor() 3312 . mat - the initial matrix 3313 . info - options for factorization 3314 - fact - the symbolic factor of mat 3315 3316 Notes: 3317 Most users should employ the simplified KSP interface for linear solvers 3318 instead of working directly with matrix algebra routines such as this. 3319 See, e.g., KSPCreate(). 3320 3321 Level: developer 3322 3323 .seealso: `MatCholeskyFactorSymbolic()`, `MatCholeskyFactor()`, `MatLUFactorNumeric()` 3324 3325 Developer Note: fortran interface is not autogenerated as the f90 3326 interface definition cannot be generated correctly [due to MatFactorInfo] 3327 3328 @*/ 3329 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3330 { 3331 MatFactorInfo tinfo; 3332 3333 PetscFunctionBegin; 3334 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3335 PetscValidType(mat,2); 3336 PetscValidPointer(fact,1); 3337 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3338 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3339 PetscCheck((fact)->ops->choleskyfactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3340 PetscCheck(mat->rmap->N == (fact)->rmap->N && mat->cmap->N == (fact)->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3341 MatCheckPreallocated(mat,2); 3342 if (!info) { 3343 PetscCall(MatFactorInfoInitialize(&tinfo)); 3344 info = &tinfo; 3345 } 3346 3347 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3348 else PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,fact,0,0)); 3349 PetscCall((fact->ops->choleskyfactornumeric)(fact,mat,info)); 3350 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3351 else PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,fact,0,0)); 3352 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3353 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3354 PetscFunctionReturn(0); 3355 } 3356 3357 /*@ 3358 MatQRFactor - Performs in-place QR factorization of matrix. 3359 3360 Collective on Mat 3361 3362 Input Parameters: 3363 + mat - the matrix 3364 . col - column permutation 3365 - info - options for factorization, includes 3366 $ fill - expected fill as ratio of original fill. 3367 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3368 $ Run with the option -info to determine an optimal value to use 3369 3370 Notes: 3371 Most users should employ the simplified KSP interface for linear solvers 3372 instead of working directly with matrix algebra routines such as this. 3373 See, e.g., KSPCreate(). 3374 3375 This changes the state of the matrix to a factored matrix; it cannot be used 3376 for example with MatSetValues() unless one first calls MatSetUnfactored(). 3377 3378 Level: developer 3379 3380 .seealso: `MatQRFactorSymbolic()`, `MatQRFactorNumeric()`, `MatLUFactor()`, 3381 `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 3382 3383 Developer Note: fortran interface is not autogenerated as the f90 3384 interface definition cannot be generated correctly [due to MatFactorInfo] 3385 3386 @*/ 3387 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info) 3388 { 3389 PetscFunctionBegin; 3390 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3391 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,2); 3392 if (info) PetscValidPointer(info,3); 3393 PetscValidType(mat,1); 3394 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3395 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3396 MatCheckPreallocated(mat,1); 3397 PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,col,0,0)); 3398 PetscUseMethod(mat,"MatQRFactor_C", (Mat,IS,const MatFactorInfo*), (mat, col, info)); 3399 PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,col,0,0)); 3400 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3401 PetscFunctionReturn(0); 3402 } 3403 3404 /*@ 3405 MatQRFactorSymbolic - Performs symbolic QR factorization of matrix. 3406 Call this routine before calling MatQRFactorNumeric(). 3407 3408 Collective on Mat 3409 3410 Input Parameters: 3411 + fact - the factor matrix obtained with MatGetFactor() 3412 . mat - the matrix 3413 . col - column permutation 3414 - info - options for factorization, includes 3415 $ fill - expected fill as ratio of original fill. 3416 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3417 $ Run with the option -info to determine an optimal value to use 3418 3419 Most users should employ the simplified KSP interface for linear solvers 3420 instead of working directly with matrix algebra routines such as this. 3421 See, e.g., KSPCreate(). 3422 3423 Level: developer 3424 3425 .seealso: `MatQRFactor()`, `MatQRFactorNumeric()`, `MatLUFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3426 3427 Developer Note: fortran interface is not autogenerated as the f90 3428 interface definition cannot be generated correctly [due to MatFactorInfo] 3429 3430 @*/ 3431 PetscErrorCode MatQRFactorSymbolic(Mat fact,Mat mat,IS col,const MatFactorInfo *info) 3432 { 3433 MatFactorInfo tinfo; 3434 3435 PetscFunctionBegin; 3436 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3437 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3438 if (info) PetscValidPointer(info,4); 3439 PetscValidType(mat,2); 3440 PetscValidPointer(fact,1); 3441 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3442 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3443 MatCheckPreallocated(mat,2); 3444 if (!info) { 3445 PetscCall(MatFactorInfoInitialize(&tinfo)); 3446 info = &tinfo; 3447 } 3448 3449 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorSymbolic,fact,mat,col,0)); 3450 PetscUseMethod(fact,"MatQRFactorSymbolic_C", (Mat,Mat,IS,const MatFactorInfo*), (fact, mat, col, info)); 3451 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorSymbolic,fact,mat,col,0)); 3452 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3453 PetscFunctionReturn(0); 3454 } 3455 3456 /*@ 3457 MatQRFactorNumeric - Performs numeric QR factorization of a matrix. 3458 Call this routine after first calling MatQRFactorSymbolic(). 3459 3460 Collective on Mat 3461 3462 Input Parameters: 3463 + fact - the factor matrix obtained with MatGetFactor() 3464 . mat - the matrix 3465 - info - options for factorization 3466 3467 Notes: 3468 See MatQRFactor() for in-place factorization. 3469 3470 Most users should employ the simplified KSP interface for linear solvers 3471 instead of working directly with matrix algebra routines such as this. 3472 See, e.g., KSPCreate(). 3473 3474 Level: developer 3475 3476 .seealso: `MatQRFactorSymbolic()`, `MatLUFactor()` 3477 3478 Developer Note: fortran interface is not autogenerated as the f90 3479 interface definition cannot be generated correctly [due to MatFactorInfo] 3480 3481 @*/ 3482 PetscErrorCode MatQRFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3483 { 3484 MatFactorInfo tinfo; 3485 3486 PetscFunctionBegin; 3487 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3488 PetscValidType(mat,2); 3489 PetscValidPointer(fact,1); 3490 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3491 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3492 PetscCheck(mat->rmap->N == fact->rmap->N && mat->cmap->N == fact->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3493 3494 MatCheckPreallocated(mat,2); 3495 if (!info) { 3496 PetscCall(MatFactorInfoInitialize(&tinfo)); 3497 info = &tinfo; 3498 } 3499 3500 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorNumeric,mat,fact,0,0)); 3501 else PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,fact,0,0)); 3502 PetscUseMethod(fact,"MatQRFactorNumeric_C", (Mat,Mat,const MatFactorInfo*), (fact, mat, info)); 3503 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorNumeric,mat,fact,0,0)); 3504 else PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,fact,0,0)); 3505 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3506 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3507 PetscFunctionReturn(0); 3508 } 3509 3510 /* ----------------------------------------------------------------*/ 3511 /*@ 3512 MatSolve - Solves A x = b, given a factored matrix. 3513 3514 Neighbor-wise Collective on Mat 3515 3516 Input Parameters: 3517 + mat - the factored matrix 3518 - b - the right-hand-side vector 3519 3520 Output Parameter: 3521 . x - the result vector 3522 3523 Notes: 3524 The vectors b and x cannot be the same. I.e., one cannot 3525 call MatSolve(A,x,x). 3526 3527 Notes: 3528 Most users should employ the simplified KSP interface for linear solvers 3529 instead of working directly with matrix algebra routines such as this. 3530 See, e.g., KSPCreate(). 3531 3532 Level: developer 3533 3534 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3535 @*/ 3536 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3537 { 3538 PetscFunctionBegin; 3539 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3540 PetscValidType(mat,1); 3541 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3542 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3543 PetscCheckSameComm(mat,1,b,2); 3544 PetscCheckSameComm(mat,1,x,3); 3545 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3546 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3547 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3548 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3549 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3550 MatCheckPreallocated(mat,1); 3551 3552 PetscCall(PetscLogEventBegin(MAT_Solve,mat,b,x,0)); 3553 if (mat->factorerrortype) { 3554 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3555 PetscCall(VecSetInf(x)); 3556 } else { 3557 PetscCheck(mat->ops->solve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3558 PetscCall((*mat->ops->solve)(mat,b,x)); 3559 } 3560 PetscCall(PetscLogEventEnd(MAT_Solve,mat,b,x,0)); 3561 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3562 PetscFunctionReturn(0); 3563 } 3564 3565 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans) 3566 { 3567 Vec b,x; 3568 PetscInt N,i; 3569 PetscErrorCode (*f)(Mat,Vec,Vec); 3570 PetscBool Abound,Bneedconv = PETSC_FALSE,Xneedconv = PETSC_FALSE; 3571 3572 PetscFunctionBegin; 3573 if (A->factorerrortype) { 3574 PetscCall(PetscInfo(A,"MatFactorError %d\n",A->factorerrortype)); 3575 PetscCall(MatSetInf(X)); 3576 PetscFunctionReturn(0); 3577 } 3578 f = (!trans || (!A->ops->solvetranspose && A->symmetric)) ? A->ops->solve : A->ops->solvetranspose; 3579 PetscCheck(f,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3580 PetscCall(MatBoundToCPU(A,&Abound)); 3581 if (!Abound) { 3582 PetscCall(PetscObjectTypeCompareAny((PetscObject)B,&Bneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3583 PetscCall(PetscObjectTypeCompareAny((PetscObject)X,&Xneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3584 } 3585 if (Bneedconv) { 3586 PetscCall(MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B)); 3587 } 3588 if (Xneedconv) { 3589 PetscCall(MatConvert(X,MATDENSECUDA,MAT_INPLACE_MATRIX,&X)); 3590 } 3591 PetscCall(MatGetSize(B,NULL,&N)); 3592 for (i=0; i<N; i++) { 3593 PetscCall(MatDenseGetColumnVecRead(B,i,&b)); 3594 PetscCall(MatDenseGetColumnVecWrite(X,i,&x)); 3595 PetscCall((*f)(A,b,x)); 3596 PetscCall(MatDenseRestoreColumnVecWrite(X,i,&x)); 3597 PetscCall(MatDenseRestoreColumnVecRead(B,i,&b)); 3598 } 3599 if (Bneedconv) { 3600 PetscCall(MatConvert(B,MATDENSE,MAT_INPLACE_MATRIX,&B)); 3601 } 3602 if (Xneedconv) { 3603 PetscCall(MatConvert(X,MATDENSE,MAT_INPLACE_MATRIX,&X)); 3604 } 3605 PetscFunctionReturn(0); 3606 } 3607 3608 /*@ 3609 MatMatSolve - Solves A X = B, given a factored matrix. 3610 3611 Neighbor-wise Collective on Mat 3612 3613 Input Parameters: 3614 + A - the factored matrix 3615 - B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS) 3616 3617 Output Parameter: 3618 . X - the result matrix (dense matrix) 3619 3620 Notes: 3621 If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B) except with MKL_CPARDISO; 3622 otherwise, B and X cannot be the same. 3623 3624 Notes: 3625 Most users should usually employ the simplified KSP interface for linear solvers 3626 instead of working directly with matrix algebra routines such as this. 3627 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3628 at a time. 3629 3630 Level: developer 3631 3632 .seealso: `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3633 @*/ 3634 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3635 { 3636 PetscFunctionBegin; 3637 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3638 PetscValidType(A,1); 3639 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3640 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3641 PetscCheckSameComm(A,1,B,2); 3642 PetscCheckSameComm(A,1,X,3); 3643 PetscCheck(A->cmap->N == X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3644 PetscCheck(A->rmap->N == B->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N); 3645 PetscCheck(X->cmap->N == B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3646 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3647 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3648 MatCheckPreallocated(A,1); 3649 3650 PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3651 if (!A->ops->matsolve) { 3652 PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name)); 3653 PetscCall(MatMatSolve_Basic(A,B,X,PETSC_FALSE)); 3654 } else { 3655 PetscCall((*A->ops->matsolve)(A,B,X)); 3656 } 3657 PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3658 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3659 PetscFunctionReturn(0); 3660 } 3661 3662 /*@ 3663 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3664 3665 Neighbor-wise Collective on Mat 3666 3667 Input Parameters: 3668 + A - the factored matrix 3669 - B - the right-hand-side matrix (dense matrix) 3670 3671 Output Parameter: 3672 . X - the result matrix (dense matrix) 3673 3674 Notes: 3675 The matrices B and X cannot be the same. I.e., one cannot 3676 call MatMatSolveTranspose(A,X,X). 3677 3678 Notes: 3679 Most users should usually employ the simplified KSP interface for linear solvers 3680 instead of working directly with matrix algebra routines such as this. 3681 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3682 at a time. 3683 3684 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3685 3686 Level: developer 3687 3688 .seealso: `MatMatSolve()`, `MatLUFactor()`, `MatCholeskyFactor()` 3689 @*/ 3690 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3691 { 3692 PetscFunctionBegin; 3693 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3694 PetscValidType(A,1); 3695 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3696 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3697 PetscCheckSameComm(A,1,B,2); 3698 PetscCheckSameComm(A,1,X,3); 3699 PetscCheck(X != B,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3700 PetscCheck(A->cmap->N == X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3701 PetscCheck(A->rmap->N == B->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N); 3702 PetscCheck(A->rmap->n == B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->n,B->rmap->n); 3703 PetscCheck(X->cmap->N >= B->cmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3704 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3705 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3706 MatCheckPreallocated(A,1); 3707 3708 PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3709 if (!A->ops->matsolvetranspose) { 3710 PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name)); 3711 PetscCall(MatMatSolve_Basic(A,B,X,PETSC_TRUE)); 3712 } else { 3713 PetscCall((*A->ops->matsolvetranspose)(A,B,X)); 3714 } 3715 PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3716 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3717 PetscFunctionReturn(0); 3718 } 3719 3720 /*@ 3721 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3722 3723 Neighbor-wise Collective on Mat 3724 3725 Input Parameters: 3726 + A - the factored matrix 3727 - Bt - the transpose of right-hand-side matrix 3728 3729 Output Parameter: 3730 . X - the result matrix (dense matrix) 3731 3732 Notes: 3733 Most users should usually employ the simplified KSP interface for linear solvers 3734 instead of working directly with matrix algebra routines such as this. 3735 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3736 at a time. 3737 3738 For MUMPS, it only supports centralized sparse compressed column format on the host processor for right hand side matrix. User must create B^T in sparse compressed row format on the host processor and call MatMatTransposeSolve() to implement MUMPS' MatMatSolve(). 3739 3740 Level: developer 3741 3742 .seealso: `MatMatSolve()`, `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3743 @*/ 3744 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3745 { 3746 PetscFunctionBegin; 3747 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3748 PetscValidType(A,1); 3749 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3750 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3751 PetscCheckSameComm(A,1,Bt,2); 3752 PetscCheckSameComm(A,1,X,3); 3753 3754 PetscCheck(X != Bt,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3755 PetscCheck(A->cmap->N == X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3756 PetscCheck(A->rmap->N == Bt->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,Bt->cmap->N); 3757 PetscCheck(X->cmap->N >= Bt->rmap->N,PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix"); 3758 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3759 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3760 MatCheckPreallocated(A,1); 3761 3762 PetscCheck(A->ops->mattransposesolve,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3763 PetscCall(PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0)); 3764 PetscCall((*A->ops->mattransposesolve)(A,Bt,X)); 3765 PetscCall(PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0)); 3766 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3767 PetscFunctionReturn(0); 3768 } 3769 3770 /*@ 3771 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3772 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3773 3774 Neighbor-wise Collective on Mat 3775 3776 Input Parameters: 3777 + mat - the factored matrix 3778 - b - the right-hand-side vector 3779 3780 Output Parameter: 3781 . x - the result vector 3782 3783 Notes: 3784 MatSolve() should be used for most applications, as it performs 3785 a forward solve followed by a backward solve. 3786 3787 The vectors b and x cannot be the same, i.e., one cannot 3788 call MatForwardSolve(A,x,x). 3789 3790 For matrix in seqsbaij format with block size larger than 1, 3791 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3792 MatForwardSolve() solves U^T*D y = b, and 3793 MatBackwardSolve() solves U x = y. 3794 Thus they do not provide a symmetric preconditioner. 3795 3796 Most users should employ the simplified KSP interface for linear solvers 3797 instead of working directly with matrix algebra routines such as this. 3798 See, e.g., KSPCreate(). 3799 3800 Level: developer 3801 3802 .seealso: `MatSolve()`, `MatBackwardSolve()` 3803 @*/ 3804 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3805 { 3806 PetscFunctionBegin; 3807 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3808 PetscValidType(mat,1); 3809 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3810 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3811 PetscCheckSameComm(mat,1,b,2); 3812 PetscCheckSameComm(mat,1,x,3); 3813 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3814 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3815 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3816 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3817 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3818 MatCheckPreallocated(mat,1); 3819 3820 PetscCheck(mat->ops->forwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3821 PetscCall(PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0)); 3822 PetscCall((*mat->ops->forwardsolve)(mat,b,x)); 3823 PetscCall(PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0)); 3824 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3825 PetscFunctionReturn(0); 3826 } 3827 3828 /*@ 3829 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3830 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3831 3832 Neighbor-wise Collective on Mat 3833 3834 Input Parameters: 3835 + mat - the factored matrix 3836 - b - the right-hand-side vector 3837 3838 Output Parameter: 3839 . x - the result vector 3840 3841 Notes: 3842 MatSolve() should be used for most applications, as it performs 3843 a forward solve followed by a backward solve. 3844 3845 The vectors b and x cannot be the same. I.e., one cannot 3846 call MatBackwardSolve(A,x,x). 3847 3848 For matrix in seqsbaij format with block size larger than 1, 3849 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3850 MatForwardSolve() solves U^T*D y = b, and 3851 MatBackwardSolve() solves U x = y. 3852 Thus they do not provide a symmetric preconditioner. 3853 3854 Most users should employ the simplified KSP interface for linear solvers 3855 instead of working directly with matrix algebra routines such as this. 3856 See, e.g., KSPCreate(). 3857 3858 Level: developer 3859 3860 .seealso: `MatSolve()`, `MatForwardSolve()` 3861 @*/ 3862 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3863 { 3864 PetscFunctionBegin; 3865 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3866 PetscValidType(mat,1); 3867 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3868 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3869 PetscCheckSameComm(mat,1,b,2); 3870 PetscCheckSameComm(mat,1,x,3); 3871 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3872 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3873 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3874 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3875 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3876 MatCheckPreallocated(mat,1); 3877 3878 PetscCheck(mat->ops->backwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3879 PetscCall(PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0)); 3880 PetscCall((*mat->ops->backwardsolve)(mat,b,x)); 3881 PetscCall(PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0)); 3882 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3883 PetscFunctionReturn(0); 3884 } 3885 3886 /*@ 3887 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3888 3889 Neighbor-wise Collective on Mat 3890 3891 Input Parameters: 3892 + mat - the factored matrix 3893 . b - the right-hand-side vector 3894 - y - the vector to be added to 3895 3896 Output Parameter: 3897 . x - the result vector 3898 3899 Notes: 3900 The vectors b and x cannot be the same. I.e., one cannot 3901 call MatSolveAdd(A,x,y,x). 3902 3903 Most users should employ the simplified KSP interface for linear solvers 3904 instead of working directly with matrix algebra routines such as this. 3905 See, e.g., KSPCreate(). 3906 3907 Level: developer 3908 3909 .seealso: `MatSolve()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3910 @*/ 3911 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3912 { 3913 PetscScalar one = 1.0; 3914 Vec tmp; 3915 3916 PetscFunctionBegin; 3917 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3918 PetscValidType(mat,1); 3919 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3920 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3921 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3922 PetscCheckSameComm(mat,1,b,2); 3923 PetscCheckSameComm(mat,1,y,3); 3924 PetscCheckSameComm(mat,1,x,4); 3925 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3926 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3927 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3928 PetscCheck(mat->rmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N); 3929 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3930 PetscCheck(x->map->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,x->map->n,y->map->n); 3931 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3932 MatCheckPreallocated(mat,1); 3933 3934 PetscCall(PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y)); 3935 if (mat->factorerrortype) { 3936 3937 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3938 PetscCall(VecSetInf(x)); 3939 } else if (mat->ops->solveadd) { 3940 PetscCall((*mat->ops->solveadd)(mat,b,y,x)); 3941 } else { 3942 /* do the solve then the add manually */ 3943 if (x != y) { 3944 PetscCall(MatSolve(mat,b,x)); 3945 PetscCall(VecAXPY(x,one,y)); 3946 } else { 3947 PetscCall(VecDuplicate(x,&tmp)); 3948 PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 3949 PetscCall(VecCopy(x,tmp)); 3950 PetscCall(MatSolve(mat,b,x)); 3951 PetscCall(VecAXPY(x,one,tmp)); 3952 PetscCall(VecDestroy(&tmp)); 3953 } 3954 } 3955 PetscCall(PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y)); 3956 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3957 PetscFunctionReturn(0); 3958 } 3959 3960 /*@ 3961 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3962 3963 Neighbor-wise Collective on Mat 3964 3965 Input Parameters: 3966 + mat - the factored matrix 3967 - b - the right-hand-side vector 3968 3969 Output Parameter: 3970 . x - the result vector 3971 3972 Notes: 3973 The vectors b and x cannot be the same. I.e., one cannot 3974 call MatSolveTranspose(A,x,x). 3975 3976 Most users should employ the simplified KSP interface for linear solvers 3977 instead of working directly with matrix algebra routines such as this. 3978 See, e.g., KSPCreate(). 3979 3980 Level: developer 3981 3982 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTransposeAdd()` 3983 @*/ 3984 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3985 { 3986 PetscErrorCode (*f)(Mat,Vec,Vec) = (!mat->ops->solvetranspose && mat->symmetric) ? mat->ops->solve : mat->ops->solvetranspose; 3987 3988 PetscFunctionBegin; 3989 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3990 PetscValidType(mat,1); 3991 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3992 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3993 PetscCheckSameComm(mat,1,b,2); 3994 PetscCheckSameComm(mat,1,x,3); 3995 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3996 PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 3997 PetscCheck(mat->cmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,b->map->N); 3998 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3999 MatCheckPreallocated(mat,1); 4000 PetscCall(PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0)); 4001 if (mat->factorerrortype) { 4002 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 4003 PetscCall(VecSetInf(x)); 4004 } else { 4005 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 4006 PetscCall((*f)(mat,b,x)); 4007 } 4008 PetscCall(PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0)); 4009 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4010 PetscFunctionReturn(0); 4011 } 4012 4013 /*@ 4014 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 4015 factored matrix. 4016 4017 Neighbor-wise Collective on Mat 4018 4019 Input Parameters: 4020 + mat - the factored matrix 4021 . b - the right-hand-side vector 4022 - y - the vector to be added to 4023 4024 Output Parameter: 4025 . x - the result vector 4026 4027 Notes: 4028 The vectors b and x cannot be the same. I.e., one cannot 4029 call MatSolveTransposeAdd(A,x,y,x). 4030 4031 Most users should employ the simplified KSP interface for linear solvers 4032 instead of working directly with matrix algebra routines such as this. 4033 See, e.g., KSPCreate(). 4034 4035 Level: developer 4036 4037 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTranspose()` 4038 @*/ 4039 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 4040 { 4041 PetscScalar one = 1.0; 4042 Vec tmp; 4043 PetscErrorCode (*f)(Mat,Vec,Vec,Vec) = (!mat->ops->solvetransposeadd && mat->symmetric) ? mat->ops->solveadd : mat->ops->solvetransposeadd; 4044 4045 PetscFunctionBegin; 4046 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4047 PetscValidType(mat,1); 4048 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 4049 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4050 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 4051 PetscCheckSameComm(mat,1,b,2); 4052 PetscCheckSameComm(mat,1,y,3); 4053 PetscCheckSameComm(mat,1,x,4); 4054 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 4055 PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 4056 PetscCheck(mat->cmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,b->map->N); 4057 PetscCheck(mat->cmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 4058 PetscCheck(x->map->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,x->map->n,y->map->n); 4059 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 4060 MatCheckPreallocated(mat,1); 4061 4062 PetscCall(PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y)); 4063 if (mat->factorerrortype) { 4064 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 4065 PetscCall(VecSetInf(x)); 4066 } else if (f) { 4067 PetscCall((*f)(mat,b,y,x)); 4068 } else { 4069 /* do the solve then the add manually */ 4070 if (x != y) { 4071 PetscCall(MatSolveTranspose(mat,b,x)); 4072 PetscCall(VecAXPY(x,one,y)); 4073 } else { 4074 PetscCall(VecDuplicate(x,&tmp)); 4075 PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 4076 PetscCall(VecCopy(x,tmp)); 4077 PetscCall(MatSolveTranspose(mat,b,x)); 4078 PetscCall(VecAXPY(x,one,tmp)); 4079 PetscCall(VecDestroy(&tmp)); 4080 } 4081 } 4082 PetscCall(PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y)); 4083 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4084 PetscFunctionReturn(0); 4085 } 4086 /* ----------------------------------------------------------------*/ 4087 4088 /*@ 4089 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 4090 4091 Neighbor-wise Collective on Mat 4092 4093 Input Parameters: 4094 + mat - the matrix 4095 . b - the right hand side 4096 . omega - the relaxation factor 4097 . flag - flag indicating the type of SOR (see below) 4098 . shift - diagonal shift 4099 . its - the number of iterations 4100 - lits - the number of local iterations 4101 4102 Output Parameter: 4103 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 4104 4105 SOR Flags: 4106 + SOR_FORWARD_SWEEP - forward SOR 4107 . SOR_BACKWARD_SWEEP - backward SOR 4108 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 4109 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 4110 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 4111 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 4112 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 4113 upper/lower triangular part of matrix to 4114 vector (with omega) 4115 - SOR_ZERO_INITIAL_GUESS - zero initial guess 4116 4117 Notes: 4118 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 4119 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 4120 on each processor. 4121 4122 Application programmers will not generally use MatSOR() directly, 4123 but instead will employ the KSP/PC interface. 4124 4125 Notes: 4126 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 4127 4128 Notes for Advanced Users: 4129 The flags are implemented as bitwise inclusive or operations. 4130 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 4131 to specify a zero initial guess for SSOR. 4132 4133 Most users should employ the simplified KSP interface for linear solvers 4134 instead of working directly with matrix algebra routines such as this. 4135 See, e.g., KSPCreate(). 4136 4137 Vectors x and b CANNOT be the same 4138 4139 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 4140 4141 Level: developer 4142 4143 @*/ 4144 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 4145 { 4146 PetscFunctionBegin; 4147 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4148 PetscValidType(mat,1); 4149 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4150 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 4151 PetscCheckSameComm(mat,1,b,2); 4152 PetscCheckSameComm(mat,1,x,8); 4153 PetscCheck(mat->ops->sor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4154 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4155 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4156 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 4157 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 4158 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 4159 PetscCheck(its > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " positive",its); 4160 PetscCheck(lits > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %" PetscInt_FMT " positive",lits); 4161 PetscCheck(b != x,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 4162 4163 MatCheckPreallocated(mat,1); 4164 PetscCall(PetscLogEventBegin(MAT_SOR,mat,b,x,0)); 4165 PetscCall((*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x)); 4166 PetscCall(PetscLogEventEnd(MAT_SOR,mat,b,x,0)); 4167 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4168 PetscFunctionReturn(0); 4169 } 4170 4171 /* 4172 Default matrix copy routine. 4173 */ 4174 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 4175 { 4176 PetscInt i,rstart = 0,rend = 0,nz; 4177 const PetscInt *cwork; 4178 const PetscScalar *vwork; 4179 4180 PetscFunctionBegin; 4181 if (B->assembled) PetscCall(MatZeroEntries(B)); 4182 if (str == SAME_NONZERO_PATTERN) { 4183 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 4184 for (i=rstart; i<rend; i++) { 4185 PetscCall(MatGetRow(A,i,&nz,&cwork,&vwork)); 4186 PetscCall(MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES)); 4187 PetscCall(MatRestoreRow(A,i,&nz,&cwork,&vwork)); 4188 } 4189 } else { 4190 PetscCall(MatAYPX(B,0.0,A,str)); 4191 } 4192 PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 4193 PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 4194 PetscFunctionReturn(0); 4195 } 4196 4197 /*@ 4198 MatCopy - Copies a matrix to another matrix. 4199 4200 Collective on Mat 4201 4202 Input Parameters: 4203 + A - the matrix 4204 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 4205 4206 Output Parameter: 4207 . B - where the copy is put 4208 4209 Notes: 4210 If you use SAME_NONZERO_PATTERN then the two matrices must have the same nonzero pattern or the routine will crash. 4211 4212 MatCopy() copies the matrix entries of a matrix to another existing 4213 matrix (after first zeroing the second matrix). A related routine is 4214 MatConvert(), which first creates a new matrix and then copies the data. 4215 4216 Level: intermediate 4217 4218 .seealso: `MatConvert()`, `MatDuplicate()` 4219 @*/ 4220 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 4221 { 4222 PetscInt i; 4223 4224 PetscFunctionBegin; 4225 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4226 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4227 PetscValidType(A,1); 4228 PetscValidType(B,2); 4229 PetscCheckSameComm(A,1,B,2); 4230 MatCheckPreallocated(B,2); 4231 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4232 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4233 PetscCheck(A->rmap->N == B->rmap->N && A->cmap->N == B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%" PetscInt_FMT ",%" PetscInt_FMT ") (%" PetscInt_FMT ",%" PetscInt_FMT ")",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N); 4234 MatCheckPreallocated(A,1); 4235 if (A == B) PetscFunctionReturn(0); 4236 4237 PetscCall(PetscLogEventBegin(MAT_Copy,A,B,0,0)); 4238 if (A->ops->copy) { 4239 PetscCall((*A->ops->copy)(A,B,str)); 4240 } else { /* generic conversion */ 4241 PetscCall(MatCopy_Basic(A,B,str)); 4242 } 4243 4244 B->stencil.dim = A->stencil.dim; 4245 B->stencil.noc = A->stencil.noc; 4246 for (i=0; i<=A->stencil.dim; i++) { 4247 B->stencil.dims[i] = A->stencil.dims[i]; 4248 B->stencil.starts[i] = A->stencil.starts[i]; 4249 } 4250 4251 PetscCall(PetscLogEventEnd(MAT_Copy,A,B,0,0)); 4252 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4253 PetscFunctionReturn(0); 4254 } 4255 4256 /*@C 4257 MatConvert - Converts a matrix to another matrix, either of the same 4258 or different type. 4259 4260 Collective on Mat 4261 4262 Input Parameters: 4263 + mat - the matrix 4264 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4265 same type as the original matrix. 4266 - reuse - denotes if the destination matrix is to be created or reused. 4267 Use MAT_INPLACE_MATRIX for inplace conversion (that is when you want the input mat to be changed to contain the matrix in the new format), otherwise use 4268 MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX (can only be used after the first call was made with MAT_INITIAL_MATRIX, causes the matrix space in M to be reused). 4269 4270 Output Parameter: 4271 . M - pointer to place new matrix 4272 4273 Notes: 4274 MatConvert() first creates a new matrix and then copies the data from 4275 the first matrix. A related routine is MatCopy(), which copies the matrix 4276 entries of one matrix to another already existing matrix context. 4277 4278 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4279 the MPI communicator of the generated matrix is always the same as the communicator 4280 of the input matrix. 4281 4282 Level: intermediate 4283 4284 .seealso: `MatCopy()`, `MatDuplicate()` 4285 @*/ 4286 PetscErrorCode MatConvert(Mat mat,MatType newtype,MatReuse reuse,Mat *M) 4287 { 4288 PetscBool sametype,issame,flg; 4289 PetscBool3 issymmetric,ishermitian; 4290 char convname[256],mtype[256]; 4291 Mat B; 4292 4293 PetscFunctionBegin; 4294 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4295 PetscValidType(mat,1); 4296 PetscValidPointer(M,4); 4297 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4298 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4299 MatCheckPreallocated(mat,1); 4300 4301 PetscCall(PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,sizeof(mtype),&flg)); 4302 if (flg) newtype = mtype; 4303 4304 PetscCall(PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype)); 4305 PetscCall(PetscStrcmp(newtype,"same",&issame)); 4306 PetscCheck(!(reuse == MAT_INPLACE_MATRIX) || !(mat != *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4307 PetscCheck(!(reuse == MAT_REUSE_MATRIX) || !(mat == *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX"); 4308 4309 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4310 PetscCall(PetscInfo(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4311 PetscFunctionReturn(0); 4312 } 4313 4314 /* Cache Mat options because some converters use MatHeaderReplace */ 4315 issymmetric = mat->symmetric; 4316 ishermitian = mat->hermitian; 4317 4318 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4319 PetscCall(PetscInfo(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4320 PetscCall((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M)); 4321 } else { 4322 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4323 const char *prefix[3] = {"seq","mpi",""}; 4324 PetscInt i; 4325 /* 4326 Order of precedence: 4327 0) See if newtype is a superclass of the current matrix. 4328 1) See if a specialized converter is known to the current matrix. 4329 2) See if a specialized converter is known to the desired matrix class. 4330 3) See if a good general converter is registered for the desired class 4331 (as of 6/27/03 only MATMPIADJ falls into this category). 4332 4) See if a good general converter is known for the current matrix. 4333 5) Use a really basic converter. 4334 */ 4335 4336 /* 0) See if newtype is a superclass of the current matrix. 4337 i.e mat is mpiaij and newtype is aij */ 4338 for (i=0; i<2; i++) { 4339 PetscCall(PetscStrncpy(convname,prefix[i],sizeof(convname))); 4340 PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 4341 PetscCall(PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg)); 4342 PetscCall(PetscInfo(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg)); 4343 if (flg) { 4344 if (reuse == MAT_INPLACE_MATRIX) { 4345 PetscCall(PetscInfo(mat,"Early return\n")); 4346 PetscFunctionReturn(0); 4347 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4348 PetscCall(PetscInfo(mat,"Calling MatDuplicate\n")); 4349 PetscCall((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M)); 4350 PetscFunctionReturn(0); 4351 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4352 PetscCall(PetscInfo(mat,"Calling MatCopy\n")); 4353 PetscCall(MatCopy(mat,*M,SAME_NONZERO_PATTERN)); 4354 PetscFunctionReturn(0); 4355 } 4356 } 4357 } 4358 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4359 for (i=0; i<3; i++) { 4360 PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4361 PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4362 PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 4363 PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4364 PetscCall(PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname))); 4365 PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 4366 PetscCall(PetscObjectQueryFunction((PetscObject)mat,convname,&conv)); 4367 PetscCall(PetscInfo(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv)); 4368 if (conv) goto foundconv; 4369 } 4370 4371 /* 2) See if a specialized converter is known to the desired matrix class. */ 4372 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&B)); 4373 PetscCall(MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 4374 PetscCall(MatSetType(B,newtype)); 4375 for (i=0; i<3; i++) { 4376 PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4377 PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4378 PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 4379 PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4380 PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 4381 PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 4382 PetscCall(PetscObjectQueryFunction((PetscObject)B,convname,&conv)); 4383 PetscCall(PetscInfo(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv)); 4384 if (conv) { 4385 PetscCall(MatDestroy(&B)); 4386 goto foundconv; 4387 } 4388 } 4389 4390 /* 3) See if a good general converter is registered for the desired class */ 4391 conv = B->ops->convertfrom; 4392 PetscCall(PetscInfo(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv)); 4393 PetscCall(MatDestroy(&B)); 4394 if (conv) goto foundconv; 4395 4396 /* 4) See if a good general converter is known for the current matrix */ 4397 if (mat->ops->convert) conv = mat->ops->convert; 4398 PetscCall(PetscInfo(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv)); 4399 if (conv) goto foundconv; 4400 4401 /* 5) Use a really basic converter. */ 4402 PetscCall(PetscInfo(mat,"Using MatConvert_Basic\n")); 4403 conv = MatConvert_Basic; 4404 4405 foundconv: 4406 PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4407 PetscCall((*conv)(mat,newtype,reuse,M)); 4408 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4409 /* the block sizes must be same if the mappings are copied over */ 4410 (*M)->rmap->bs = mat->rmap->bs; 4411 (*M)->cmap->bs = mat->cmap->bs; 4412 PetscCall(PetscObjectReference((PetscObject)mat->rmap->mapping)); 4413 PetscCall(PetscObjectReference((PetscObject)mat->cmap->mapping)); 4414 (*M)->rmap->mapping = mat->rmap->mapping; 4415 (*M)->cmap->mapping = mat->cmap->mapping; 4416 } 4417 (*M)->stencil.dim = mat->stencil.dim; 4418 (*M)->stencil.noc = mat->stencil.noc; 4419 for (i=0; i<=mat->stencil.dim; i++) { 4420 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4421 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4422 } 4423 PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4424 } 4425 PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 4426 4427 /* Copy Mat options */ 4428 if (issymmetric == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE)); 4429 else if (issymmetric == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M,MAT_SYMMETRIC,PETSC_FALSE)); 4430 if (ishermitian == PETSC_BOOL3_TRUE) PetscCall(MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE)); 4431 else if (ishermitian == PETSC_BOOL3_FALSE) PetscCall(MatSetOption(*M,MAT_HERMITIAN,PETSC_FALSE)); 4432 PetscFunctionReturn(0); 4433 } 4434 4435 /*@C 4436 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4437 4438 Not Collective 4439 4440 Input Parameter: 4441 . mat - the matrix, must be a factored matrix 4442 4443 Output Parameter: 4444 . type - the string name of the package (do not free this string) 4445 4446 Notes: 4447 In Fortran you pass in a empty string and the package name will be copied into it. 4448 (Make sure the string is long enough) 4449 4450 Level: intermediate 4451 4452 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4453 @*/ 4454 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4455 { 4456 PetscErrorCode (*conv)(Mat,MatSolverType*); 4457 4458 PetscFunctionBegin; 4459 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4460 PetscValidType(mat,1); 4461 PetscValidPointer(type,2); 4462 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4463 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv)); 4464 if (conv) PetscCall((*conv)(mat,type)); 4465 else *type = MATSOLVERPETSC; 4466 PetscFunctionReturn(0); 4467 } 4468 4469 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4470 struct _MatSolverTypeForSpecifcType { 4471 MatType mtype; 4472 /* no entry for MAT_FACTOR_NONE */ 4473 PetscErrorCode (*createfactor[MAT_FACTOR_NUM_TYPES-1])(Mat,MatFactorType,Mat*); 4474 MatSolverTypeForSpecifcType next; 4475 }; 4476 4477 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4478 struct _MatSolverTypeHolder { 4479 char *name; 4480 MatSolverTypeForSpecifcType handlers; 4481 MatSolverTypeHolder next; 4482 }; 4483 4484 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4485 4486 /*@C 4487 MatSolverTypeRegister - Registers a MatSolverType that works for a particular matrix type 4488 4489 Input Parameters: 4490 + package - name of the package, for example petsc or superlu 4491 . mtype - the matrix type that works with this package 4492 . ftype - the type of factorization supported by the package 4493 - createfactor - routine that will create the factored matrix ready to be used 4494 4495 Level: intermediate 4496 4497 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4498 @*/ 4499 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*createfactor)(Mat,MatFactorType,Mat*)) 4500 { 4501 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4502 PetscBool flg; 4503 MatSolverTypeForSpecifcType inext,iprev = NULL; 4504 4505 PetscFunctionBegin; 4506 PetscCall(MatInitializePackage()); 4507 if (!next) { 4508 PetscCall(PetscNew(&MatSolverTypeHolders)); 4509 PetscCall(PetscStrallocpy(package,&MatSolverTypeHolders->name)); 4510 PetscCall(PetscNew(&MatSolverTypeHolders->handlers)); 4511 PetscCall(PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype)); 4512 MatSolverTypeHolders->handlers->createfactor[(int)ftype-1] = createfactor; 4513 PetscFunctionReturn(0); 4514 } 4515 while (next) { 4516 PetscCall(PetscStrcasecmp(package,next->name,&flg)); 4517 if (flg) { 4518 PetscCheck(next->handlers,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4519 inext = next->handlers; 4520 while (inext) { 4521 PetscCall(PetscStrcasecmp(mtype,inext->mtype,&flg)); 4522 if (flg) { 4523 inext->createfactor[(int)ftype-1] = createfactor; 4524 PetscFunctionReturn(0); 4525 } 4526 iprev = inext; 4527 inext = inext->next; 4528 } 4529 PetscCall(PetscNew(&iprev->next)); 4530 PetscCall(PetscStrallocpy(mtype,(char **)&iprev->next->mtype)); 4531 iprev->next->createfactor[(int)ftype-1] = createfactor; 4532 PetscFunctionReturn(0); 4533 } 4534 prev = next; 4535 next = next->next; 4536 } 4537 PetscCall(PetscNew(&prev->next)); 4538 PetscCall(PetscStrallocpy(package,&prev->next->name)); 4539 PetscCall(PetscNew(&prev->next->handlers)); 4540 PetscCall(PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype)); 4541 prev->next->handlers->createfactor[(int)ftype-1] = createfactor; 4542 PetscFunctionReturn(0); 4543 } 4544 4545 /*@C 4546 MatSolverTypeGet - Gets the function that creates the factor matrix if it exist 4547 4548 Input Parameters: 4549 + type - name of the package, for example petsc or superlu 4550 . ftype - the type of factorization supported by the type 4551 - mtype - the matrix type that works with this type 4552 4553 Output Parameters: 4554 + foundtype - PETSC_TRUE if the type was registered 4555 . foundmtype - PETSC_TRUE if the type supports the requested mtype 4556 - createfactor - routine that will create the factored matrix ready to be used or NULL if not found 4557 4558 Level: intermediate 4559 4560 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatSolverTypeRegister()`, `MatGetFactor()` 4561 @*/ 4562 PetscErrorCode MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool *foundtype,PetscBool *foundmtype,PetscErrorCode (**createfactor)(Mat,MatFactorType,Mat*)) 4563 { 4564 MatSolverTypeHolder next = MatSolverTypeHolders; 4565 PetscBool flg; 4566 MatSolverTypeForSpecifcType inext; 4567 4568 PetscFunctionBegin; 4569 if (foundtype) *foundtype = PETSC_FALSE; 4570 if (foundmtype) *foundmtype = PETSC_FALSE; 4571 if (createfactor) *createfactor = NULL; 4572 4573 if (type) { 4574 while (next) { 4575 PetscCall(PetscStrcasecmp(type,next->name,&flg)); 4576 if (flg) { 4577 if (foundtype) *foundtype = PETSC_TRUE; 4578 inext = next->handlers; 4579 while (inext) { 4580 PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4581 if (flg) { 4582 if (foundmtype) *foundmtype = PETSC_TRUE; 4583 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4584 PetscFunctionReturn(0); 4585 } 4586 inext = inext->next; 4587 } 4588 } 4589 next = next->next; 4590 } 4591 } else { 4592 while (next) { 4593 inext = next->handlers; 4594 while (inext) { 4595 PetscCall(PetscStrcmp(mtype,inext->mtype,&flg)); 4596 if (flg && inext->createfactor[(int)ftype-1]) { 4597 if (foundtype) *foundtype = PETSC_TRUE; 4598 if (foundmtype) *foundmtype = PETSC_TRUE; 4599 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4600 PetscFunctionReturn(0); 4601 } 4602 inext = inext->next; 4603 } 4604 next = next->next; 4605 } 4606 /* try with base classes inext->mtype */ 4607 next = MatSolverTypeHolders; 4608 while (next) { 4609 inext = next->handlers; 4610 while (inext) { 4611 PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4612 if (flg && inext->createfactor[(int)ftype-1]) { 4613 if (foundtype) *foundtype = PETSC_TRUE; 4614 if (foundmtype) *foundmtype = PETSC_TRUE; 4615 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4616 PetscFunctionReturn(0); 4617 } 4618 inext = inext->next; 4619 } 4620 next = next->next; 4621 } 4622 } 4623 PetscFunctionReturn(0); 4624 } 4625 4626 PetscErrorCode MatSolverTypeDestroy(void) 4627 { 4628 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4629 MatSolverTypeForSpecifcType inext,iprev; 4630 4631 PetscFunctionBegin; 4632 while (next) { 4633 PetscCall(PetscFree(next->name)); 4634 inext = next->handlers; 4635 while (inext) { 4636 PetscCall(PetscFree(inext->mtype)); 4637 iprev = inext; 4638 inext = inext->next; 4639 PetscCall(PetscFree(iprev)); 4640 } 4641 prev = next; 4642 next = next->next; 4643 PetscCall(PetscFree(prev)); 4644 } 4645 MatSolverTypeHolders = NULL; 4646 PetscFunctionReturn(0); 4647 } 4648 4649 /*@C 4650 MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4651 4652 Logically Collective on Mat 4653 4654 Input Parameters: 4655 . mat - the matrix 4656 4657 Output Parameters: 4658 . flg - PETSC_TRUE if uses the ordering 4659 4660 Notes: 4661 Most internal PETSc factorizations use the ordering passed to the factorization routine but external 4662 packages do not, thus we want to skip generating the ordering when it is not needed or used. 4663 4664 Level: developer 4665 4666 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4667 @*/ 4668 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg) 4669 { 4670 PetscFunctionBegin; 4671 *flg = mat->canuseordering; 4672 PetscFunctionReturn(0); 4673 } 4674 4675 /*@C 4676 MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object 4677 4678 Logically Collective on Mat 4679 4680 Input Parameters: 4681 . mat - the matrix 4682 4683 Output Parameters: 4684 . otype - the preferred type 4685 4686 Level: developer 4687 4688 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4689 @*/ 4690 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype) 4691 { 4692 PetscFunctionBegin; 4693 *otype = mat->preferredordering[ftype]; 4694 PetscCheck(*otype,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatFactor did not have a preferred ordering"); 4695 PetscFunctionReturn(0); 4696 } 4697 4698 /*@C 4699 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4700 4701 Collective on Mat 4702 4703 Input Parameters: 4704 + mat - the matrix 4705 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4706 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4707 4708 Output Parameters: 4709 . f - the factor matrix used with MatXXFactorSymbolic() calls 4710 4711 Options Database Key: 4712 . -mat_factor_bind_factorization <host, device> - Where to do matrix factorization? Default is device (might consume more device memory. 4713 One can choose host to save device memory). Currently only supported with SEQAIJCUSPARSE matrices. 4714 4715 Notes: 4716 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4717 such as pastix, superlu, mumps etc. 4718 4719 PETSc must have been ./configure to use the external solver, using the option --download-package 4720 4721 Some of the packages have options for controlling the factorization, these are in the form -prefix_mat_packagename_packageoption 4722 where prefix is normally obtained from the calling `KSP`/`PC`. If `MatGetFactor()` is called directly one can set 4723 call `MatSetOptionsPrefixFactor()` on the originating matrix or `MatSetOptionsPrefix()` on the resulting factor matrix. 4724 4725 Developer Notes: 4726 This should actually be called MatCreateFactor() since it creates a new factor object 4727 4728 Level: intermediate 4729 4730 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatFactorGetCanUseOrdering()`, `MatSolverTypeRegister()` 4731 @*/ 4732 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4733 { 4734 PetscBool foundtype,foundmtype; 4735 PetscErrorCode (*conv)(Mat,MatFactorType,Mat*); 4736 4737 PetscFunctionBegin; 4738 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4739 PetscValidType(mat,1); 4740 4741 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4742 MatCheckPreallocated(mat,1); 4743 4744 PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv)); 4745 if (!foundtype) { 4746 if (type) { 4747 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver type %s for factorization type %s and matrix type %s. Perhaps you must ./configure with --download-%s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name,type); 4748 } else { 4749 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver type for factorization type %s and matrix type %s.",MatFactorTypes[ftype],((PetscObject)mat)->type_name); 4750 } 4751 } 4752 PetscCheck(foundmtype,PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4753 PetscCheck(conv,PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support factorization type %s for matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name); 4754 4755 PetscCall((*conv)(mat,ftype,f)); 4756 if (mat->factorprefix) PetscCall(MatSetOptionsPrefix(*f,mat->factorprefix)); 4757 PetscFunctionReturn(0); 4758 } 4759 4760 /*@C 4761 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type 4762 4763 Not Collective 4764 4765 Input Parameters: 4766 + mat - the matrix 4767 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4768 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4769 4770 Output Parameter: 4771 . flg - PETSC_TRUE if the factorization is available 4772 4773 Notes: 4774 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4775 such as pastix, superlu, mumps etc. 4776 4777 PETSc must have been ./configure to use the external solver, using the option --download-package 4778 4779 Developer Notes: 4780 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object 4781 4782 Level: intermediate 4783 4784 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactor()`, `MatSolverTypeRegister()` 4785 @*/ 4786 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4787 { 4788 PetscErrorCode (*gconv)(Mat,MatFactorType,Mat*); 4789 4790 PetscFunctionBegin; 4791 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4792 PetscValidType(mat,1); 4793 PetscValidBoolPointer(flg,4); 4794 4795 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4796 MatCheckPreallocated(mat,1); 4797 4798 PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv)); 4799 *flg = gconv ? PETSC_TRUE : PETSC_FALSE; 4800 PetscFunctionReturn(0); 4801 } 4802 4803 /*@ 4804 MatDuplicate - Duplicates a matrix including the non-zero structure. 4805 4806 Collective on Mat 4807 4808 Input Parameters: 4809 + mat - the matrix 4810 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4811 See the manual page for MatDuplicateOption for an explanation of these options. 4812 4813 Output Parameter: 4814 . M - pointer to place new matrix 4815 4816 Level: intermediate 4817 4818 Notes: 4819 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4820 May be called with an unassembled input Mat if MAT_DO_NOT_COPY_VALUES is used, in which case the output Mat is unassembled as well. 4821 When original mat is a product of matrix operation, e.g., an output of MatMatMult() or MatCreateSubMatrix(), only the simple matrix data structure of mat is duplicated and the internal data structures created for the reuse of previous matrix operations are not duplicated. User should not use MatDuplicate() to create new matrix M if M is intended to be reused as the product of matrix operation. 4822 4823 .seealso: `MatCopy()`, `MatConvert()`, `MatDuplicateOption` 4824 @*/ 4825 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4826 { 4827 Mat B; 4828 VecType vtype; 4829 PetscInt i; 4830 PetscObject dm; 4831 void (*viewf)(void); 4832 4833 PetscFunctionBegin; 4834 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4835 PetscValidType(mat,1); 4836 PetscValidPointer(M,3); 4837 PetscCheck(op != MAT_COPY_VALUES || mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4838 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4839 MatCheckPreallocated(mat,1); 4840 4841 *M = NULL; 4842 PetscCheck(mat->ops->duplicate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s",((PetscObject)mat)->type_name); 4843 PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4844 PetscCall((*mat->ops->duplicate)(mat,op,M)); 4845 PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4846 B = *M; 4847 4848 PetscCall(MatGetOperation(mat,MATOP_VIEW,&viewf)); 4849 if (viewf) PetscCall(MatSetOperation(B,MATOP_VIEW,viewf)); 4850 PetscCall(MatGetVecType(mat,&vtype)); 4851 PetscCall(MatSetVecType(B,vtype)); 4852 4853 B->stencil.dim = mat->stencil.dim; 4854 B->stencil.noc = mat->stencil.noc; 4855 for (i=0; i<=mat->stencil.dim; i++) { 4856 B->stencil.dims[i] = mat->stencil.dims[i]; 4857 B->stencil.starts[i] = mat->stencil.starts[i]; 4858 } 4859 4860 B->nooffproczerorows = mat->nooffproczerorows; 4861 B->nooffprocentries = mat->nooffprocentries; 4862 4863 PetscCall(PetscObjectQuery((PetscObject) mat, "__PETSc_dm", &dm)); 4864 if (dm) { 4865 PetscCall(PetscObjectCompose((PetscObject) B, "__PETSc_dm", dm)); 4866 } 4867 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4868 PetscFunctionReturn(0); 4869 } 4870 4871 /*@ 4872 MatGetDiagonal - Gets the diagonal of a matrix. 4873 4874 Logically Collective on Mat 4875 4876 Input Parameters: 4877 + mat - the matrix 4878 - v - the vector for storing the diagonal 4879 4880 Output Parameter: 4881 . v - the diagonal of the matrix 4882 4883 Level: intermediate 4884 4885 Note: 4886 Currently only correct in parallel for square matrices. 4887 4888 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()` 4889 @*/ 4890 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4891 { 4892 PetscFunctionBegin; 4893 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4894 PetscValidType(mat,1); 4895 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4896 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4897 PetscCheck(mat->ops->getdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4898 MatCheckPreallocated(mat,1); 4899 4900 PetscCall((*mat->ops->getdiagonal)(mat,v)); 4901 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4902 PetscFunctionReturn(0); 4903 } 4904 4905 /*@C 4906 MatGetRowMin - Gets the minimum value (of the real part) of each 4907 row of the matrix 4908 4909 Logically Collective on Mat 4910 4911 Input Parameter: 4912 . mat - the matrix 4913 4914 Output Parameters: 4915 + v - the vector for storing the maximums 4916 - idx - the indices of the column found for each row (optional) 4917 4918 Level: intermediate 4919 4920 Notes: 4921 The result of this call are the same as if one converted the matrix to dense format 4922 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4923 4924 This code is only implemented for a couple of matrix formats. 4925 4926 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, 4927 `MatGetRowMax()` 4928 @*/ 4929 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4930 { 4931 PetscFunctionBegin; 4932 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4933 PetscValidType(mat,1); 4934 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4935 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4936 4937 if (!mat->cmap->N) { 4938 PetscCall(VecSet(v,PETSC_MAX_REAL)); 4939 if (idx) { 4940 PetscInt i,m = mat->rmap->n; 4941 for (i=0; i<m; i++) idx[i] = -1; 4942 } 4943 } else { 4944 PetscCheck(mat->ops->getrowmin,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4945 MatCheckPreallocated(mat,1); 4946 } 4947 PetscCall((*mat->ops->getrowmin)(mat,v,idx)); 4948 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4949 PetscFunctionReturn(0); 4950 } 4951 4952 /*@C 4953 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4954 row of the matrix 4955 4956 Logically Collective on Mat 4957 4958 Input Parameter: 4959 . mat - the matrix 4960 4961 Output Parameters: 4962 + v - the vector for storing the minimums 4963 - idx - the indices of the column found for each row (or NULL if not needed) 4964 4965 Level: intermediate 4966 4967 Notes: 4968 if a row is completely empty or has only 0.0 values then the idx[] value for that 4969 row is 0 (the first column). 4970 4971 This code is only implemented for a couple of matrix formats. 4972 4973 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 4974 @*/ 4975 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4976 { 4977 PetscFunctionBegin; 4978 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4979 PetscValidType(mat,1); 4980 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4981 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4982 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4983 4984 if (!mat->cmap->N) { 4985 PetscCall(VecSet(v,0.0)); 4986 if (idx) { 4987 PetscInt i,m = mat->rmap->n; 4988 for (i=0; i<m; i++) idx[i] = -1; 4989 } 4990 } else { 4991 PetscCheck(mat->ops->getrowminabs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4992 MatCheckPreallocated(mat,1); 4993 if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n)); 4994 PetscCall((*mat->ops->getrowminabs)(mat,v,idx)); 4995 } 4996 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4997 PetscFunctionReturn(0); 4998 } 4999 5000 /*@C 5001 MatGetRowMax - Gets the maximum value (of the real part) of each 5002 row of the matrix 5003 5004 Logically Collective on Mat 5005 5006 Input Parameter: 5007 . mat - the matrix 5008 5009 Output Parameters: 5010 + v - the vector for storing the maximums 5011 - idx - the indices of the column found for each row (optional) 5012 5013 Level: intermediate 5014 5015 Notes: 5016 The result of this call are the same as if one converted the matrix to dense format 5017 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 5018 5019 This code is only implemented for a couple of matrix formats. 5020 5021 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 5022 @*/ 5023 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 5024 { 5025 PetscFunctionBegin; 5026 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5027 PetscValidType(mat,1); 5028 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5029 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5030 5031 if (!mat->cmap->N) { 5032 PetscCall(VecSet(v,PETSC_MIN_REAL)); 5033 if (idx) { 5034 PetscInt i,m = mat->rmap->n; 5035 for (i=0; i<m; i++) idx[i] = -1; 5036 } 5037 } else { 5038 PetscCheck(mat->ops->getrowmax,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5039 MatCheckPreallocated(mat,1); 5040 PetscCall((*mat->ops->getrowmax)(mat,v,idx)); 5041 } 5042 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5043 PetscFunctionReturn(0); 5044 } 5045 5046 /*@C 5047 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 5048 row of the matrix 5049 5050 Logically Collective on Mat 5051 5052 Input Parameter: 5053 . mat - the matrix 5054 5055 Output Parameters: 5056 + v - the vector for storing the maximums 5057 - idx - the indices of the column found for each row (or NULL if not needed) 5058 5059 Level: intermediate 5060 5061 Notes: 5062 if a row is completely empty or has only 0.0 values then the idx[] value for that 5063 row is 0 (the first column). 5064 5065 This code is only implemented for a couple of matrix formats. 5066 5067 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 5068 @*/ 5069 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 5070 { 5071 PetscFunctionBegin; 5072 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5073 PetscValidType(mat,1); 5074 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5075 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5076 5077 if (!mat->cmap->N) { 5078 PetscCall(VecSet(v,0.0)); 5079 if (idx) { 5080 PetscInt i,m = mat->rmap->n; 5081 for (i=0; i<m; i++) idx[i] = -1; 5082 } 5083 } else { 5084 PetscCheck(mat->ops->getrowmaxabs,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5085 MatCheckPreallocated(mat,1); 5086 if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n)); 5087 PetscCall((*mat->ops->getrowmaxabs)(mat,v,idx)); 5088 } 5089 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5090 PetscFunctionReturn(0); 5091 } 5092 5093 /*@ 5094 MatGetRowSum - Gets the sum of each row of the matrix 5095 5096 Logically or Neighborhood Collective on Mat 5097 5098 Input Parameters: 5099 . mat - the matrix 5100 5101 Output Parameter: 5102 . v - the vector for storing the sum of rows 5103 5104 Level: intermediate 5105 5106 Notes: 5107 This code is slow since it is not currently specialized for different formats 5108 5109 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 5110 @*/ 5111 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 5112 { 5113 Vec ones; 5114 5115 PetscFunctionBegin; 5116 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5117 PetscValidType(mat,1); 5118 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5119 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5120 MatCheckPreallocated(mat,1); 5121 PetscCall(MatCreateVecs(mat,&ones,NULL)); 5122 PetscCall(VecSet(ones,1.)); 5123 PetscCall(MatMult(mat,ones,v)); 5124 PetscCall(VecDestroy(&ones)); 5125 PetscFunctionReturn(0); 5126 } 5127 5128 /*@ 5129 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 5130 5131 Collective on Mat 5132 5133 Input Parameters: 5134 + mat - the matrix to transpose 5135 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5136 5137 Output Parameter: 5138 . B - the transpose 5139 5140 Notes: 5141 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 5142 5143 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 5144 5145 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 5146 5147 Level: intermediate 5148 5149 .seealso: `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5150 @*/ 5151 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 5152 { 5153 PetscFunctionBegin; 5154 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5155 PetscValidType(mat,1); 5156 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5157 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5158 PetscCheck(mat->ops->transpose,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5159 PetscCheck(reuse != MAT_INPLACE_MATRIX || mat == *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 5160 PetscCheck(reuse != MAT_REUSE_MATRIX || mat != *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 5161 MatCheckPreallocated(mat,1); 5162 5163 PetscCall(PetscLogEventBegin(MAT_Transpose,mat,0,0,0)); 5164 PetscCall((*mat->ops->transpose)(mat,reuse,B)); 5165 PetscCall(PetscLogEventEnd(MAT_Transpose,mat,0,0,0)); 5166 if (B) PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5167 PetscFunctionReturn(0); 5168 } 5169 5170 /*@ 5171 MatIsTranspose - Test whether a matrix is another one's transpose, 5172 or its own, in which case it tests symmetry. 5173 5174 Collective on Mat 5175 5176 Input Parameters: 5177 + A - the matrix to test 5178 - B - the matrix to test against, this can equal the first parameter 5179 5180 Output Parameters: 5181 . flg - the result 5182 5183 Notes: 5184 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5185 has a running time of the order of the number of nonzeros; the parallel 5186 test involves parallel copies of the block-offdiagonal parts of the matrix. 5187 5188 Level: intermediate 5189 5190 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()` 5191 @*/ 5192 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5193 { 5194 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5195 5196 PetscFunctionBegin; 5197 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5198 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5199 PetscValidBoolPointer(flg,4); 5200 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f)); 5201 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g)); 5202 *flg = PETSC_FALSE; 5203 if (f && g) { 5204 PetscCheck(f == g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 5205 PetscCall((*f)(A,B,tol,flg)); 5206 } else { 5207 MatType mattype; 5208 5209 PetscCall(MatGetType(f ? B : A,&mattype)); 5210 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype); 5211 } 5212 PetscFunctionReturn(0); 5213 } 5214 5215 /*@ 5216 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5217 5218 Collective on Mat 5219 5220 Input Parameters: 5221 + mat - the matrix to transpose and complex conjugate 5222 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5223 5224 Output Parameter: 5225 . B - the Hermitian 5226 5227 Level: intermediate 5228 5229 .seealso: `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5230 @*/ 5231 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5232 { 5233 PetscFunctionBegin; 5234 PetscCall(MatTranspose(mat,reuse,B)); 5235 #if defined(PETSC_USE_COMPLEX) 5236 PetscCall(MatConjugate(*B)); 5237 #endif 5238 PetscFunctionReturn(0); 5239 } 5240 5241 /*@ 5242 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5243 5244 Collective on Mat 5245 5246 Input Parameters: 5247 + A - the matrix to test 5248 - B - the matrix to test against, this can equal the first parameter 5249 5250 Output Parameters: 5251 . flg - the result 5252 5253 Notes: 5254 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5255 has a running time of the order of the number of nonzeros; the parallel 5256 test involves parallel copies of the block-offdiagonal parts of the matrix. 5257 5258 Level: intermediate 5259 5260 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsTranspose()` 5261 @*/ 5262 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5263 { 5264 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5265 5266 PetscFunctionBegin; 5267 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5268 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5269 PetscValidBoolPointer(flg,4); 5270 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f)); 5271 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g)); 5272 if (f && g) { 5273 PetscCheck(f != g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5274 PetscCall((*f)(A,B,tol,flg)); 5275 } 5276 PetscFunctionReturn(0); 5277 } 5278 5279 /*@ 5280 MatPermute - Creates a new matrix with rows and columns permuted from the 5281 original. 5282 5283 Collective on Mat 5284 5285 Input Parameters: 5286 + mat - the matrix to permute 5287 . row - row permutation, each processor supplies only the permutation for its rows 5288 - col - column permutation, each processor supplies only the permutation for its columns 5289 5290 Output Parameters: 5291 . B - the permuted matrix 5292 5293 Level: advanced 5294 5295 Note: 5296 The index sets map from row/col of permuted matrix to row/col of original matrix. 5297 The index sets should be on the same communicator as Mat and have the same local sizes. 5298 5299 Developer Note: 5300 If you want to implement MatPermute for a matrix type, and your approach doesn't 5301 exploit the fact that row and col are permutations, consider implementing the 5302 more general MatCreateSubMatrix() instead. 5303 5304 .seealso: `MatGetOrdering()`, `ISAllGather()` 5305 5306 @*/ 5307 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5308 { 5309 PetscFunctionBegin; 5310 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5311 PetscValidType(mat,1); 5312 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5313 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5314 PetscValidPointer(B,4); 5315 PetscCheckSameComm(mat,1,row,2); 5316 if (row != col) PetscCheckSameComm(row,2,col,3); 5317 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5318 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5319 PetscCheck(mat->ops->permute || mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5320 MatCheckPreallocated(mat,1); 5321 5322 if (mat->ops->permute) { 5323 PetscCall((*mat->ops->permute)(mat,row,col,B)); 5324 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5325 } else { 5326 PetscCall(MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B)); 5327 } 5328 PetscFunctionReturn(0); 5329 } 5330 5331 /*@ 5332 MatEqual - Compares two matrices. 5333 5334 Collective on Mat 5335 5336 Input Parameters: 5337 + A - the first matrix 5338 - B - the second matrix 5339 5340 Output Parameter: 5341 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5342 5343 Level: intermediate 5344 5345 @*/ 5346 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5347 { 5348 PetscFunctionBegin; 5349 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5350 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5351 PetscValidType(A,1); 5352 PetscValidType(B,2); 5353 PetscValidBoolPointer(flg,3); 5354 PetscCheckSameComm(A,1,B,2); 5355 MatCheckPreallocated(A,1); 5356 MatCheckPreallocated(B,2); 5357 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5358 PetscCheck(B->assembled,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5359 PetscCheck(A->rmap->N == B->rmap->N && A->cmap->N == B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N); 5360 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5361 PetscCall((*A->ops->equal)(A,B,flg)); 5362 } else { 5363 PetscCall(MatMultEqual(A,B,10,flg)); 5364 } 5365 PetscFunctionReturn(0); 5366 } 5367 5368 /*@ 5369 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5370 matrices that are stored as vectors. Either of the two scaling 5371 matrices can be NULL. 5372 5373 Collective on Mat 5374 5375 Input Parameters: 5376 + mat - the matrix to be scaled 5377 . l - the left scaling vector (or NULL) 5378 - r - the right scaling vector (or NULL) 5379 5380 Notes: 5381 MatDiagonalScale() computes A = LAR, where 5382 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5383 The L scales the rows of the matrix, the R scales the columns of the matrix. 5384 5385 Level: intermediate 5386 5387 .seealso: `MatScale()`, `MatShift()`, `MatDiagonalSet()` 5388 @*/ 5389 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5390 { 5391 PetscFunctionBegin; 5392 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5393 PetscValidType(mat,1); 5394 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5395 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5396 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5397 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5398 MatCheckPreallocated(mat,1); 5399 if (!l && !r) PetscFunctionReturn(0); 5400 5401 PetscCheck(mat->ops->diagonalscale,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5402 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5403 PetscCall((*mat->ops->diagonalscale)(mat,l,r)); 5404 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5405 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5406 if (l != r) mat->symmetric = PETSC_BOOL3_FALSE; 5407 PetscFunctionReturn(0); 5408 } 5409 5410 /*@ 5411 MatScale - Scales all elements of a matrix by a given number. 5412 5413 Logically Collective on Mat 5414 5415 Input Parameters: 5416 + mat - the matrix to be scaled 5417 - a - the scaling value 5418 5419 Output Parameter: 5420 . mat - the scaled matrix 5421 5422 Level: intermediate 5423 5424 .seealso: `MatDiagonalScale()` 5425 @*/ 5426 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5427 { 5428 PetscFunctionBegin; 5429 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5430 PetscValidType(mat,1); 5431 PetscCheck(a == (PetscScalar)1.0 || mat->ops->scale,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5432 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5433 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5434 PetscValidLogicalCollectiveScalar(mat,a,2); 5435 MatCheckPreallocated(mat,1); 5436 5437 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5438 if (a != (PetscScalar)1.0) { 5439 PetscCall((*mat->ops->scale)(mat,a)); 5440 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5441 } 5442 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5443 PetscFunctionReturn(0); 5444 } 5445 5446 /*@ 5447 MatNorm - Calculates various norms of a matrix. 5448 5449 Collective on Mat 5450 5451 Input Parameters: 5452 + mat - the matrix 5453 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5454 5455 Output Parameter: 5456 . nrm - the resulting norm 5457 5458 Level: intermediate 5459 5460 @*/ 5461 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5462 { 5463 PetscFunctionBegin; 5464 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5465 PetscValidType(mat,1); 5466 PetscValidRealPointer(nrm,3); 5467 5468 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5469 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5470 PetscCheck(mat->ops->norm,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5471 MatCheckPreallocated(mat,1); 5472 5473 PetscCall((*mat->ops->norm)(mat,type,nrm)); 5474 PetscFunctionReturn(0); 5475 } 5476 5477 /* 5478 This variable is used to prevent counting of MatAssemblyBegin() that 5479 are called from within a MatAssemblyEnd(). 5480 */ 5481 static PetscInt MatAssemblyEnd_InUse = 0; 5482 /*@ 5483 MatAssemblyBegin - Begins assembling the matrix. This routine should 5484 be called after completing all calls to MatSetValues(). 5485 5486 Collective on Mat 5487 5488 Input Parameters: 5489 + mat - the matrix 5490 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5491 5492 Notes: 5493 MatSetValues() generally caches the values. The matrix is ready to 5494 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5495 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5496 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5497 using the matrix. 5498 5499 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5500 same flag of MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY for all processes. Thus you CANNOT locally change from ADD_VALUES to INSERT_VALUES, that is 5501 a global collective operation requring all processes that share the matrix. 5502 5503 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5504 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5505 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5506 5507 Level: beginner 5508 5509 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssembled()` 5510 @*/ 5511 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5512 { 5513 PetscFunctionBegin; 5514 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5515 PetscValidType(mat,1); 5516 MatCheckPreallocated(mat,1); 5517 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5518 if (mat->assembled) { 5519 mat->was_assembled = PETSC_TRUE; 5520 mat->assembled = PETSC_FALSE; 5521 } 5522 5523 if (!MatAssemblyEnd_InUse) { 5524 PetscCall(PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0)); 5525 if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5526 PetscCall(PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0)); 5527 } else if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5528 PetscFunctionReturn(0); 5529 } 5530 5531 /*@ 5532 MatAssembled - Indicates if a matrix has been assembled and is ready for 5533 use; for example, in matrix-vector product. 5534 5535 Not Collective 5536 5537 Input Parameter: 5538 . mat - the matrix 5539 5540 Output Parameter: 5541 . assembled - PETSC_TRUE or PETSC_FALSE 5542 5543 Level: advanced 5544 5545 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssemblyBegin()` 5546 @*/ 5547 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5548 { 5549 PetscFunctionBegin; 5550 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5551 PetscValidBoolPointer(assembled,2); 5552 *assembled = mat->assembled; 5553 PetscFunctionReturn(0); 5554 } 5555 5556 /*@ 5557 MatAssemblyEnd - Completes assembling the matrix. This routine should 5558 be called after MatAssemblyBegin(). 5559 5560 Collective on Mat 5561 5562 Input Parameters: 5563 + mat - the matrix 5564 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5565 5566 Options Database Keys: 5567 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5568 . -mat_view ::ascii_info_detail - Prints more detailed info 5569 . -mat_view - Prints matrix in ASCII format 5570 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5571 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5572 . -display <name> - Sets display name (default is host) 5573 . -draw_pause <sec> - Sets number of seconds to pause after display 5574 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab) 5575 . -viewer_socket_machine <machine> - Machine to use for socket 5576 . -viewer_socket_port <port> - Port number to use for socket 5577 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5578 5579 Notes: 5580 MatSetValues() generally caches the values. The matrix is ready to 5581 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5582 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5583 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5584 using the matrix. 5585 5586 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5587 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5588 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5589 5590 Level: beginner 5591 5592 .seealso: `MatAssemblyBegin()`, `MatSetValues()`, `PetscDrawOpenX()`, `PetscDrawCreate()`, `MatView()`, `MatAssembled()`, `PetscViewerSocketOpen()` 5593 @*/ 5594 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5595 { 5596 static PetscInt inassm = 0; 5597 PetscBool flg = PETSC_FALSE; 5598 5599 PetscFunctionBegin; 5600 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5601 PetscValidType(mat,1); 5602 5603 inassm++; 5604 MatAssemblyEnd_InUse++; 5605 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5606 PetscCall(PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0)); 5607 if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5608 PetscCall(PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0)); 5609 } else if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5610 5611 /* Flush assembly is not a true assembly */ 5612 if (type != MAT_FLUSH_ASSEMBLY) { 5613 if (mat->num_ass) { 5614 if (!mat->symmetry_eternal) { 5615 mat->symmetric = PETSC_BOOL3_UNKNOWN; 5616 mat->hermitian = PETSC_BOOL3_UNKNOWN; 5617 } 5618 if (!mat->structural_symmetry_eternal && mat->ass_nonzerostate != mat->nonzerostate) { 5619 mat->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 5620 } 5621 if (!mat->spd_eternal) mat->spd = PETSC_BOOL3_UNKNOWN; 5622 } 5623 mat->num_ass++; 5624 mat->assembled = PETSC_TRUE; 5625 mat->ass_nonzerostate = mat->nonzerostate; 5626 } 5627 5628 mat->insertmode = NOT_SET_VALUES; 5629 MatAssemblyEnd_InUse--; 5630 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5631 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5632 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 5633 5634 if (mat->checksymmetryonassembly) { 5635 PetscCall(MatIsSymmetric(mat,mat->checksymmetrytol,&flg)); 5636 if (flg) { 5637 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5638 } else { 5639 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5640 } 5641 } 5642 if (mat->nullsp && mat->checknullspaceonassembly) { 5643 PetscCall(MatNullSpaceTest(mat->nullsp,mat,NULL)); 5644 } 5645 } 5646 inassm--; 5647 PetscFunctionReturn(0); 5648 } 5649 5650 /*@ 5651 MatSetOption - Sets a parameter option for a matrix. Some options 5652 may be specific to certain storage formats. Some options 5653 determine how values will be inserted (or added). Sorted, 5654 row-oriented input will generally assemble the fastest. The default 5655 is row-oriented. 5656 5657 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5658 5659 Input Parameters: 5660 + mat - the matrix 5661 . option - the option, one of those listed below (and possibly others), 5662 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5663 5664 Options Describing Matrix Structure: 5665 + MAT_SPD - symmetric positive definite 5666 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5667 . MAT_HERMITIAN - transpose is the complex conjugation 5668 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5669 - MAT_SYMMETRY_ETERNAL - indicates the symmetry (or Hermitian structure) or its absence will persist through any changes to the matrix 5670 - MAT_STRUCTURAL_SYMMETRY_ETERNAL - indicates the structural symmetry or its absence will persist through any changes to the matrix 5671 5672 These are not really options of the matrix, they are knowledge about the structure of the matrix that users may provide so that they 5673 do not need to be computed (usually at a high cost) 5674 5675 Options For Use with MatSetValues(): 5676 Insert a logically dense subblock, which can be 5677 . MAT_ROW_ORIENTED - row-oriented (default) 5678 5679 Note these options reflect the data you pass in with MatSetValues(); it has 5680 nothing to do with how the data is stored internally in the matrix 5681 data structure. 5682 5683 When (re)assembling a matrix, we can restrict the input for 5684 efficiency/debugging purposes. These options include 5685 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5686 . MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated 5687 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5688 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5689 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5690 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5691 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5692 performance for very large process counts. 5693 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5694 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5695 functions, instead sending only neighbor messages. 5696 5697 Notes: 5698 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5699 5700 Some options are relevant only for particular matrix types and 5701 are thus ignored by others. Other options are not supported by 5702 certain matrix types and will generate an error message if set. 5703 5704 If using a Fortran 77 module to compute a matrix, one may need to 5705 use the column-oriented option (or convert to the row-oriented 5706 format). 5707 5708 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5709 that would generate a new entry in the nonzero structure is instead 5710 ignored. Thus, if memory has not alredy been allocated for this particular 5711 data, then the insertion is ignored. For dense matrices, in which 5712 the entire array is allocated, no entries are ever ignored. 5713 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5714 5715 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5716 that would generate a new entry in the nonzero structure instead produces 5717 an error. (Currently supported for AIJ and BAIJ formats only.) If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5718 5719 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5720 that would generate a new entry that has not been preallocated will 5721 instead produce an error. (Currently supported for AIJ and BAIJ formats 5722 only.) This is a useful flag when debugging matrix memory preallocation. 5723 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5724 5725 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5726 other processors should be dropped, rather than stashed. 5727 This is useful if you know that the "owning" processor is also 5728 always generating the correct matrix entries, so that PETSc need 5729 not transfer duplicate entries generated on another processor. 5730 5731 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5732 searches during matrix assembly. When this flag is set, the hash table 5733 is created during the first Matrix Assembly. This hash table is 5734 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5735 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5736 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5737 supported by MATMPIBAIJ format only. 5738 5739 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5740 are kept in the nonzero structure 5741 5742 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5743 a zero location in the matrix 5744 5745 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5746 5747 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5748 zero row routines and thus improves performance for very large process counts. 5749 5750 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5751 part of the matrix (since they should match the upper triangular part). 5752 5753 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5754 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5755 with finite difference schemes with non-periodic boundary conditions. 5756 5757 Level: intermediate 5758 5759 .seealso: `MatOption`, `Mat`, `MatGetOption()` 5760 5761 @*/ 5762 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5763 { 5764 PetscFunctionBegin; 5765 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5766 if (op > 0) { 5767 PetscValidLogicalCollectiveEnum(mat,op,2); 5768 PetscValidLogicalCollectiveBool(mat,flg,3); 5769 } 5770 5771 PetscCheck(((int) op) > MAT_OPTION_MIN && ((int) op) < MAT_OPTION_MAX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op); 5772 5773 switch (op) { 5774 case MAT_FORCE_DIAGONAL_ENTRIES: 5775 mat->force_diagonals = flg; 5776 PetscFunctionReturn(0); 5777 case MAT_NO_OFF_PROC_ENTRIES: 5778 mat->nooffprocentries = flg; 5779 PetscFunctionReturn(0); 5780 case MAT_SUBSET_OFF_PROC_ENTRIES: 5781 mat->assembly_subset = flg; 5782 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5783 #if !defined(PETSC_HAVE_MPIUNI) 5784 PetscCall(MatStashScatterDestroy_BTS(&mat->stash)); 5785 #endif 5786 mat->stash.first_assembly_done = PETSC_FALSE; 5787 } 5788 PetscFunctionReturn(0); 5789 case MAT_NO_OFF_PROC_ZERO_ROWS: 5790 mat->nooffproczerorows = flg; 5791 PetscFunctionReturn(0); 5792 case MAT_SPD: 5793 if (flg) { 5794 mat->spd = PETSC_BOOL3_TRUE; 5795 mat->symmetric = PETSC_BOOL3_TRUE; 5796 mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5797 } else { 5798 mat->spd = PETSC_BOOL3_FALSE; 5799 } 5800 break; 5801 case MAT_SYMMETRIC: 5802 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5803 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5804 #if !defined(PETSC_USE_COMPLEX) 5805 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5806 #endif 5807 break; 5808 case MAT_HERMITIAN: 5809 mat->hermitian = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5810 if (flg) mat->structurally_symmetric = PETSC_BOOL3_TRUE; 5811 #if !defined(PETSC_USE_COMPLEX) 5812 mat->symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5813 #endif 5814 break; 5815 case MAT_STRUCTURALLY_SYMMETRIC: 5816 mat->structurally_symmetric = flg ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE; 5817 break; 5818 case MAT_SYMMETRY_ETERNAL: 5819 mat->symmetry_eternal = flg ? PETSC_TRUE : PETSC_FALSE; 5820 if (flg) mat->structural_symmetry_eternal = PETSC_TRUE; 5821 break; 5822 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5823 mat->structural_symmetry_eternal = flg; 5824 break; 5825 case MAT_SPD_ETERNAL: 5826 mat->spd_eternal = flg; 5827 if (flg) { 5828 mat->structural_symmetry_eternal = PETSC_TRUE; 5829 mat->symmetry_eternal = PETSC_TRUE; 5830 } 5831 break; 5832 case MAT_STRUCTURE_ONLY: 5833 mat->structure_only = flg; 5834 break; 5835 case MAT_SORTED_FULL: 5836 mat->sortedfull = flg; 5837 break; 5838 default: 5839 break; 5840 } 5841 if (mat->ops->setoption) PetscCall((*mat->ops->setoption)(mat,op,flg)); 5842 PetscFunctionReturn(0); 5843 } 5844 5845 /*@ 5846 MatGetOption - Gets a parameter option that has been set for a matrix. 5847 5848 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5849 5850 Input Parameters: 5851 + mat - the matrix 5852 - option - the option, this only responds to certain options, check the code for which ones 5853 5854 Output Parameter: 5855 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5856 5857 Notes: 5858 Can only be called after MatSetSizes() and MatSetType() have been set. 5859 5860 Certain option values may be unknown, for those use the routines `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, or 5861 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5862 5863 Level: intermediate 5864 5865 .seealso: `MatOption`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, 5866 `MatIsSymmetricKnown()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetricKnown()` 5867 5868 @*/ 5869 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5870 { 5871 PetscFunctionBegin; 5872 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5873 PetscValidType(mat,1); 5874 5875 PetscCheck(((int) op) > MAT_OPTION_MIN && ((int) op) < MAT_OPTION_MAX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op); 5876 PetscCheck(((PetscObject)mat)->type_name,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()"); 5877 5878 switch (op) { 5879 case MAT_NO_OFF_PROC_ENTRIES: 5880 *flg = mat->nooffprocentries; 5881 break; 5882 case MAT_NO_OFF_PROC_ZERO_ROWS: 5883 *flg = mat->nooffproczerorows; 5884 break; 5885 case MAT_SYMMETRIC: 5886 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSymmetric() or MatIsSymmetricKnown()"); 5887 break; 5888 case MAT_HERMITIAN: 5889 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsHermitian() or MatIsHermitianKnown()"); 5890 break; 5891 case MAT_STRUCTURALLY_SYMMETRIC: 5892 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsStructurallySymmetric() or MatIsStructurallySymmetricKnown()"); 5893 break; 5894 case MAT_SPD: 5895 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Use MatIsSPDKnown()"); 5896 break; 5897 case MAT_SYMMETRY_ETERNAL: 5898 *flg = mat->symmetry_eternal; 5899 break; 5900 case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 5901 *flg = mat->symmetry_eternal; 5902 break; 5903 default: 5904 break; 5905 } 5906 PetscFunctionReturn(0); 5907 } 5908 5909 /*@ 5910 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5911 this routine retains the old nonzero structure. 5912 5913 Logically Collective on Mat 5914 5915 Input Parameters: 5916 . mat - the matrix 5917 5918 Level: intermediate 5919 5920 Notes: 5921 If the matrix was not preallocated then a default, likely poor preallocation will be set in the matrix, so this should be called after the preallocation phase. 5922 See the Performance chapter of the users manual for information on preallocating matrices. 5923 5924 .seealso: `MatZeroRows()` 5925 @*/ 5926 PetscErrorCode MatZeroEntries(Mat mat) 5927 { 5928 PetscFunctionBegin; 5929 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5930 PetscValidType(mat,1); 5931 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5932 PetscCheck(mat->insertmode == NOT_SET_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled"); 5933 PetscCheck(mat->ops->zeroentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5934 MatCheckPreallocated(mat,1); 5935 5936 PetscCall(PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0)); 5937 PetscCall((*mat->ops->zeroentries)(mat)); 5938 PetscCall(PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0)); 5939 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5940 PetscFunctionReturn(0); 5941 } 5942 5943 /*@ 5944 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5945 of a set of rows and columns of a matrix. 5946 5947 Collective on Mat 5948 5949 Input Parameters: 5950 + mat - the matrix 5951 . numRows - the number of rows to remove 5952 . rows - the global row indices 5953 . diag - value put in the diagonal of the eliminated rows 5954 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 5955 - b - optional vector of right hand side, that will be adjusted by provided solution 5956 5957 Notes: 5958 This routine, along with `MatZeroRows()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 5959 5960 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 5961 The other entries of b will be adjusted by the known values of x times the corresponding matrix entries in the columns that are being eliminated 5962 5963 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 5964 Krylov method to take advantage of the known solution on the zeroed rows. 5965 5966 For the parallel case, all processes that share the matrix (i.e., 5967 those in the communicator used for matrix creation) MUST call this 5968 routine, regardless of whether any rows being zeroed are owned by 5969 them. 5970 5971 Unlike `MatZeroRows()` this does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5972 5973 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5974 list only rows local to itself). 5975 5976 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5977 5978 Level: intermediate 5979 5980 .seealso: `MatZeroRowsIS()`, `MatZeroRows()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 5981 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 5982 @*/ 5983 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5984 { 5985 PetscFunctionBegin; 5986 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5987 PetscValidType(mat,1); 5988 if (numRows) PetscValidIntPointer(rows,3); 5989 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5990 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5991 PetscCheck(mat->ops->zerorowscolumns,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5992 MatCheckPreallocated(mat,1); 5993 5994 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b)); 5995 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 5996 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5997 PetscFunctionReturn(0); 5998 } 5999 6000 /*@ 6001 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 6002 of a set of rows and columns of a matrix. 6003 6004 Collective on Mat 6005 6006 Input Parameters: 6007 + mat - the matrix 6008 . is - the rows to zero 6009 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6010 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6011 - b - optional vector of right hand side, that will be adjusted by provided solution 6012 6013 Note: 6014 See `MatZeroRowsColumns()` for details on how this routine operates. 6015 6016 Level: intermediate 6017 6018 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6019 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRows()`, `MatZeroRowsColumnsStencil()` 6020 @*/ 6021 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6022 { 6023 PetscInt numRows; 6024 const PetscInt *rows; 6025 6026 PetscFunctionBegin; 6027 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6028 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6029 PetscValidType(mat,1); 6030 PetscValidType(is,2); 6031 PetscCall(ISGetLocalSize(is,&numRows)); 6032 PetscCall(ISGetIndices(is,&rows)); 6033 PetscCall(MatZeroRowsColumns(mat,numRows,rows,diag,x,b)); 6034 PetscCall(ISRestoreIndices(is,&rows)); 6035 PetscFunctionReturn(0); 6036 } 6037 6038 /*@ 6039 MatZeroRows - Zeros all entries (except possibly the main diagonal) 6040 of a set of rows of a matrix. 6041 6042 Collective on Mat 6043 6044 Input Parameters: 6045 + mat - the matrix 6046 . numRows - the number of rows to remove 6047 . rows - the global row indices 6048 . diag - value put in the diagonal of the eliminated rows 6049 . x - optional vector of solutions for zeroed rows (other entries in vector are not used), these must be set before this call 6050 - b - optional vector of right hand side, that will be adjusted by provided solution 6051 6052 Notes: 6053 This routine, along with `MatZeroRowsColumns()`, is typically used to eliminate known Dirichlet boundary conditions from a linear system. 6054 6055 For each zeroed row, the value of the corresponding b is set to diag times the value of the corresponding x. 6056 6057 If the resulting linear system is to be solved with KSP then one can (but does not have to) call `KSPSetInitialGuessNonzero()` to allow the 6058 Krylov method to take advantage of the known solution on the zeroed rows. 6059 6060 May be followed by using a `PC` of type `PCREDISTRIBUTE` to solve the reducing problem (after completely eliminating the zeroed rows and their corresponding columns) 6061 from the matrix. 6062 6063 Unlike `MatZeroRowsColumns()` for the AIJ and BAIJ matrix formats this removes the old nonzero structure, from the eliminated rows of the matrix 6064 but does not release memory. Because of this removal matrix-vector products with the adjusted matrix will be a bit faster. For the dense and block diagonal 6065 formats this does not alter the nonzero structure. 6066 6067 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6068 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6069 merely zeroed. 6070 6071 The user can set a value in the diagonal entry (or for the AIJ and 6072 row formats can optionally remove the main diagonal entry from the 6073 nonzero structure as well, by passing 0.0 as the final argument). 6074 6075 For the parallel case, all processes that share the matrix (i.e., 6076 those in the communicator used for matrix creation) MUST call this 6077 routine, regardless of whether any rows being zeroed are owned by 6078 them. 6079 6080 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6081 list only rows local to itself). 6082 6083 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6084 owns that are to be zeroed. This saves a global synchronization in the implementation. 6085 6086 Level: intermediate 6087 6088 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6089 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()`, `PCREDISTRIBUTE` 6090 @*/ 6091 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6092 { 6093 PetscFunctionBegin; 6094 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6095 PetscValidType(mat,1); 6096 if (numRows) PetscValidIntPointer(rows,3); 6097 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6098 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6099 PetscCheck(mat->ops->zerorows,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6100 MatCheckPreallocated(mat,1); 6101 6102 PetscCall((*mat->ops->zerorows)(mat,numRows,rows,diag,x,b)); 6103 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6104 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6105 PetscFunctionReturn(0); 6106 } 6107 6108 /*@ 6109 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 6110 of a set of rows of a matrix. 6111 6112 Collective on Mat 6113 6114 Input Parameters: 6115 + mat - the matrix 6116 . is - index set of rows to remove (if NULL then no row is removed) 6117 . diag - value put in all diagonals of eliminated rows 6118 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6119 - b - optional vector of right hand side, that will be adjusted by provided solution 6120 6121 Note: 6122 See `MatZeroRows()` for details on how this routine operates. 6123 6124 Level: intermediate 6125 6126 .seealso: `MatZeroRows()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6127 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6128 @*/ 6129 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6130 { 6131 PetscInt numRows = 0; 6132 const PetscInt *rows = NULL; 6133 6134 PetscFunctionBegin; 6135 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6136 PetscValidType(mat,1); 6137 if (is) { 6138 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6139 PetscCall(ISGetLocalSize(is,&numRows)); 6140 PetscCall(ISGetIndices(is,&rows)); 6141 } 6142 PetscCall(MatZeroRows(mat,numRows,rows,diag,x,b)); 6143 if (is) { 6144 PetscCall(ISRestoreIndices(is,&rows)); 6145 } 6146 PetscFunctionReturn(0); 6147 } 6148 6149 /*@ 6150 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6151 of a set of rows of a matrix. These rows must be local to the process. 6152 6153 Collective on Mat 6154 6155 Input Parameters: 6156 + mat - the matrix 6157 . numRows - the number of rows to remove 6158 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6159 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6160 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6161 - b - optional vector of right hand side, that will be adjusted by provided solution 6162 6163 Notes: 6164 See `MatZeroRows()` for details on how this routine operates. 6165 6166 The grid coordinates are across the entire grid, not just the local portion 6167 6168 In Fortran idxm and idxn should be declared as 6169 $ MatStencil idxm(4,m) 6170 and the values inserted using 6171 $ idxm(MatStencil_i,1) = i 6172 $ idxm(MatStencil_j,1) = j 6173 $ idxm(MatStencil_k,1) = k 6174 $ idxm(MatStencil_c,1) = c 6175 etc 6176 6177 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6178 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6179 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6180 DM_BOUNDARY_PERIODIC boundary type. 6181 6182 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 6183 a single value per point) you can skip filling those indices. 6184 6185 Level: intermediate 6186 6187 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsl()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6188 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6189 @*/ 6190 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6191 { 6192 PetscInt dim = mat->stencil.dim; 6193 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6194 PetscInt *dims = mat->stencil.dims+1; 6195 PetscInt *starts = mat->stencil.starts; 6196 PetscInt *dxm = (PetscInt*) rows; 6197 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6198 6199 PetscFunctionBegin; 6200 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6201 PetscValidType(mat,1); 6202 if (numRows) PetscValidPointer(rows,3); 6203 6204 PetscCall(PetscMalloc1(numRows, &jdxm)); 6205 for (i = 0; i < numRows; ++i) { 6206 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6207 for (j = 0; j < 3-sdim; ++j) dxm++; 6208 /* Local index in X dir */ 6209 tmp = *dxm++ - starts[0]; 6210 /* Loop over remaining dimensions */ 6211 for (j = 0; j < dim-1; ++j) { 6212 /* If nonlocal, set index to be negative */ 6213 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6214 /* Update local index */ 6215 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6216 } 6217 /* Skip component slot if necessary */ 6218 if (mat->stencil.noc) dxm++; 6219 /* Local row number */ 6220 if (tmp >= 0) { 6221 jdxm[numNewRows++] = tmp; 6222 } 6223 } 6224 PetscCall(MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b)); 6225 PetscCall(PetscFree(jdxm)); 6226 PetscFunctionReturn(0); 6227 } 6228 6229 /*@ 6230 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6231 of a set of rows and columns of a matrix. 6232 6233 Collective on Mat 6234 6235 Input Parameters: 6236 + mat - the matrix 6237 . numRows - the number of rows/columns to remove 6238 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6239 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6240 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6241 - b - optional vector of right hand side, that will be adjusted by provided solution 6242 6243 Notes: 6244 See `MatZeroRowsColumns()` for details on how this routine operates. 6245 6246 The grid coordinates are across the entire grid, not just the local portion 6247 6248 In Fortran idxm and idxn should be declared as 6249 $ MatStencil idxm(4,m) 6250 and the values inserted using 6251 $ idxm(MatStencil_i,1) = i 6252 $ idxm(MatStencil_j,1) = j 6253 $ idxm(MatStencil_k,1) = k 6254 $ idxm(MatStencil_c,1) = c 6255 etc 6256 6257 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6258 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6259 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6260 DM_BOUNDARY_PERIODIC boundary type. 6261 6262 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 6263 a single value per point) you can skip filling those indices. 6264 6265 Level: intermediate 6266 6267 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6268 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRows()` 6269 @*/ 6270 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6271 { 6272 PetscInt dim = mat->stencil.dim; 6273 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6274 PetscInt *dims = mat->stencil.dims+1; 6275 PetscInt *starts = mat->stencil.starts; 6276 PetscInt *dxm = (PetscInt*) rows; 6277 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6278 6279 PetscFunctionBegin; 6280 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6281 PetscValidType(mat,1); 6282 if (numRows) PetscValidPointer(rows,3); 6283 6284 PetscCall(PetscMalloc1(numRows, &jdxm)); 6285 for (i = 0; i < numRows; ++i) { 6286 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6287 for (j = 0; j < 3-sdim; ++j) dxm++; 6288 /* Local index in X dir */ 6289 tmp = *dxm++ - starts[0]; 6290 /* Loop over remaining dimensions */ 6291 for (j = 0; j < dim-1; ++j) { 6292 /* If nonlocal, set index to be negative */ 6293 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6294 /* Update local index */ 6295 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6296 } 6297 /* Skip component slot if necessary */ 6298 if (mat->stencil.noc) dxm++; 6299 /* Local row number */ 6300 if (tmp >= 0) { 6301 jdxm[numNewRows++] = tmp; 6302 } 6303 } 6304 PetscCall(MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b)); 6305 PetscCall(PetscFree(jdxm)); 6306 PetscFunctionReturn(0); 6307 } 6308 6309 /*@C 6310 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6311 of a set of rows of a matrix; using local numbering of rows. 6312 6313 Collective on Mat 6314 6315 Input Parameters: 6316 + mat - the matrix 6317 . numRows - the number of rows to remove 6318 . rows - the local row indices 6319 . diag - value put in all diagonals of eliminated rows 6320 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6321 - b - optional vector of right hand side, that will be adjusted by provided solution 6322 6323 Notes: 6324 Before calling `MatZeroRowsLocal()`, the user must first set the 6325 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6326 6327 See `MatZeroRows()` for details on how this routine operates. 6328 6329 Level: intermediate 6330 6331 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRows()`, `MatSetOption()`, 6332 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6333 @*/ 6334 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6335 { 6336 PetscFunctionBegin; 6337 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6338 PetscValidType(mat,1); 6339 if (numRows) PetscValidIntPointer(rows,3); 6340 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6341 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6342 MatCheckPreallocated(mat,1); 6343 6344 if (mat->ops->zerorowslocal) { 6345 PetscCall((*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b)); 6346 } else { 6347 IS is, newis; 6348 const PetscInt *newRows; 6349 6350 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6351 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6352 PetscCall(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis)); 6353 PetscCall(ISGetIndices(newis,&newRows)); 6354 PetscCall((*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b)); 6355 PetscCall(ISRestoreIndices(newis,&newRows)); 6356 PetscCall(ISDestroy(&newis)); 6357 PetscCall(ISDestroy(&is)); 6358 } 6359 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6360 PetscFunctionReturn(0); 6361 } 6362 6363 /*@ 6364 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6365 of a set of rows of a matrix; using local numbering of rows. 6366 6367 Collective on Mat 6368 6369 Input Parameters: 6370 + mat - the matrix 6371 . is - index set of rows to remove 6372 . diag - value put in all diagonals of eliminated rows 6373 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6374 - b - optional vector of right hand side, that will be adjusted by provided solution 6375 6376 Notes: 6377 Before calling `MatZeroRowsLocalIS()`, the user must first set the 6378 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6379 6380 See `MatZeroRows()` for details on how this routine operates. 6381 6382 Level: intermediate 6383 6384 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRows()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6385 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6386 @*/ 6387 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6388 { 6389 PetscInt numRows; 6390 const PetscInt *rows; 6391 6392 PetscFunctionBegin; 6393 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6394 PetscValidType(mat,1); 6395 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6396 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6397 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6398 MatCheckPreallocated(mat,1); 6399 6400 PetscCall(ISGetLocalSize(is,&numRows)); 6401 PetscCall(ISGetIndices(is,&rows)); 6402 PetscCall(MatZeroRowsLocal(mat,numRows,rows,diag,x,b)); 6403 PetscCall(ISRestoreIndices(is,&rows)); 6404 PetscFunctionReturn(0); 6405 } 6406 6407 /*@ 6408 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6409 of a set of rows and columns of a matrix; using local numbering of rows. 6410 6411 Collective on Mat 6412 6413 Input Parameters: 6414 + mat - the matrix 6415 . numRows - the number of rows to remove 6416 . rows - the global row indices 6417 . diag - value put in all diagonals of eliminated rows 6418 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6419 - b - optional vector of right hand side, that will be adjusted by provided solution 6420 6421 Notes: 6422 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6423 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6424 6425 See `MatZeroRowsColumns()` for details on how this routine operates. 6426 6427 Level: intermediate 6428 6429 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6430 `MatZeroRows()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6431 @*/ 6432 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6433 { 6434 IS is, newis; 6435 const PetscInt *newRows; 6436 6437 PetscFunctionBegin; 6438 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6439 PetscValidType(mat,1); 6440 if (numRows) PetscValidIntPointer(rows,3); 6441 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6442 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6443 MatCheckPreallocated(mat,1); 6444 6445 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6446 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6447 PetscCall(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis)); 6448 PetscCall(ISGetIndices(newis,&newRows)); 6449 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b)); 6450 PetscCall(ISRestoreIndices(newis,&newRows)); 6451 PetscCall(ISDestroy(&newis)); 6452 PetscCall(ISDestroy(&is)); 6453 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6454 PetscFunctionReturn(0); 6455 } 6456 6457 /*@ 6458 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6459 of a set of rows and columns of a matrix; using local numbering of rows. 6460 6461 Collective on Mat 6462 6463 Input Parameters: 6464 + mat - the matrix 6465 . is - index set of rows to remove 6466 . diag - value put in all diagonals of eliminated rows 6467 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6468 - b - optional vector of right hand side, that will be adjusted by provided solution 6469 6470 Notes: 6471 Before calling `MatZeroRowsColumnsLocalIS()`, the user must first set the 6472 local-to-global mapping by calling `MatSetLocalToGlobalMapping()`. 6473 6474 See `MatZeroRowsColumns()` for details on how this routine operates. 6475 6476 Level: intermediate 6477 6478 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6479 `MatZeroRowsColumnsLocal()`, `MatZeroRows()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6480 @*/ 6481 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6482 { 6483 PetscInt numRows; 6484 const PetscInt *rows; 6485 6486 PetscFunctionBegin; 6487 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6488 PetscValidType(mat,1); 6489 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6490 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6491 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6492 MatCheckPreallocated(mat,1); 6493 6494 PetscCall(ISGetLocalSize(is,&numRows)); 6495 PetscCall(ISGetIndices(is,&rows)); 6496 PetscCall(MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b)); 6497 PetscCall(ISRestoreIndices(is,&rows)); 6498 PetscFunctionReturn(0); 6499 } 6500 6501 /*@C 6502 MatGetSize - Returns the numbers of rows and columns in a matrix. 6503 6504 Not Collective 6505 6506 Input Parameter: 6507 . mat - the matrix 6508 6509 Output Parameters: 6510 + m - the number of global rows 6511 - n - the number of global columns 6512 6513 Note: both output parameters can be NULL on input. 6514 6515 Level: beginner 6516 6517 .seealso: `MatGetLocalSize()` 6518 @*/ 6519 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6520 { 6521 PetscFunctionBegin; 6522 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6523 if (m) *m = mat->rmap->N; 6524 if (n) *n = mat->cmap->N; 6525 PetscFunctionReturn(0); 6526 } 6527 6528 /*@C 6529 MatGetLocalSize - For most matrix formats, excluding `MATELEMENTAL` and `MATSCALAPACK`, Returns the number of local rows and local columns 6530 of a matrix. For all matrices this is the local size of the left and right vectors as returned by MatCreateVecs(). 6531 6532 Not Collective 6533 6534 Input Parameter: 6535 . mat - the matrix 6536 6537 Output Parameters: 6538 + m - the number of local rows, use `NULL` to not obtain this value 6539 - n - the number of local columns, use `NULL` to not obtain this value 6540 6541 Level: beginner 6542 6543 .seealso: `MatGetSize()` 6544 @*/ 6545 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6546 { 6547 PetscFunctionBegin; 6548 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6549 if (m) PetscValidIntPointer(m,2); 6550 if (n) PetscValidIntPointer(n,3); 6551 if (m) *m = mat->rmap->n; 6552 if (n) *n = mat->cmap->n; 6553 PetscFunctionReturn(0); 6554 } 6555 6556 /*@C 6557 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies this matrix by that are owned by 6558 this processor. (The columns of the "diagonal block" for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6559 6560 Not Collective, unless matrix has not been allocated, then collective on Mat 6561 6562 Input Parameter: 6563 . mat - the matrix 6564 6565 Output Parameters: 6566 + m - the global index of the first local column, use `NULL` to not obtain this value 6567 - n - one more than the global index of the last local column, use `NULL` to not obtain this value 6568 6569 Level: developer 6570 6571 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6572 6573 @*/ 6574 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6575 { 6576 PetscFunctionBegin; 6577 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6578 PetscValidType(mat,1); 6579 if (m) PetscValidIntPointer(m,2); 6580 if (n) PetscValidIntPointer(n,3); 6581 MatCheckPreallocated(mat,1); 6582 if (m) *m = mat->cmap->rstart; 6583 if (n) *n = mat->cmap->rend; 6584 PetscFunctionReturn(0); 6585 } 6586 6587 /*@C 6588 MatGetOwnershipRange - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6589 this MPI rank. For all matrices it returns the range of matrix rows associated with rows of a vector that would contain the result of a matrix 6590 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6591 6592 Not Collective 6593 6594 Input Parameter: 6595 . mat - the matrix 6596 6597 Output Parameters: 6598 + m - the global index of the first local row, use `NULL` to not obtain this value 6599 - n - one more than the global index of the last local row, use `NULL` to not obtain this value 6600 6601 Note: 6602 This function requires that the matrix be preallocated. If you have not preallocated, consider using 6603 `PetscSplitOwnership`(`MPI_Comm` comm, `PetscInt` *n, `PetscInt` *N) 6604 and then `MPI_Scan()` to calculate prefix sums of the local sizes. 6605 6606 Level: beginner 6607 6608 .seealso: `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`, 6609 `PetscLayout` 6610 6611 @*/ 6612 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6613 { 6614 PetscFunctionBegin; 6615 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6616 PetscValidType(mat,1); 6617 if (m) PetscValidIntPointer(m,2); 6618 if (n) PetscValidIntPointer(n,3); 6619 MatCheckPreallocated(mat,1); 6620 if (m) *m = mat->rmap->rstart; 6621 if (n) *n = mat->rmap->rend; 6622 PetscFunctionReturn(0); 6623 } 6624 6625 /*@C 6626 MatGetOwnershipRanges - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6627 each process. For all matrices it returns the ranges of matrix rows associated with rows of a vector that would contain the result of a matrix 6628 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6629 6630 Not Collective, unless matrix has not been allocated, then collective on Mat 6631 6632 Input Parameters: 6633 . mat - the matrix 6634 6635 Output Parameters: 6636 . ranges - start of each processors portion plus one more than the total length at the end 6637 6638 Level: beginner 6639 6640 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6641 6642 @*/ 6643 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6644 { 6645 PetscFunctionBegin; 6646 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6647 PetscValidType(mat,1); 6648 MatCheckPreallocated(mat,1); 6649 PetscCall(PetscLayoutGetRanges(mat->rmap,ranges)); 6650 PetscFunctionReturn(0); 6651 } 6652 6653 /*@C 6654 MatGetOwnershipRangesColumn - Returns the ranges of matrix columns associated with rows of a vector one multiplies this vector by that are owned by 6655 each processor. (The columns of the "diagonal blocks", for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6656 6657 Not Collective, unless matrix has not been allocated, then collective on Mat 6658 6659 Input Parameters: 6660 . mat - the matrix 6661 6662 Output Parameters: 6663 . ranges - start of each processors portion plus one more then the total length at the end 6664 6665 Level: beginner 6666 6667 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRanges()` 6668 6669 @*/ 6670 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6671 { 6672 PetscFunctionBegin; 6673 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6674 PetscValidType(mat,1); 6675 MatCheckPreallocated(mat,1); 6676 PetscCall(PetscLayoutGetRanges(mat->cmap,ranges)); 6677 PetscFunctionReturn(0); 6678 } 6679 6680 /*@C 6681 MatGetOwnershipIS - Get row and column ownership of a matrices' values as index sets. For most matrices, excluding `MATELEMENTAL` and `MATSCALAPACK`, this 6682 corresponds to values returned by `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`. For `MATELEMENTAL` and `MATSCALAPACK` the ownership 6683 is more complicated. See :any:`<sec_matlayout>` for details on matrix layouts. 6684 6685 Not Collective 6686 6687 Input Parameter: 6688 . A - matrix 6689 6690 Output Parameters: 6691 + rows - rows in which this process owns elements, , use `NULL` to not obtain this value 6692 - cols - columns in which this process owns elements, use `NULL` to not obtain this value 6693 6694 Level: intermediate 6695 6696 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatSetValues()`, ``MATELEMENTAL``, ``MATSCALAPACK`` 6697 @*/ 6698 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6699 { 6700 PetscErrorCode (*f)(Mat,IS*,IS*); 6701 6702 PetscFunctionBegin; 6703 MatCheckPreallocated(A,1); 6704 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f)); 6705 if (f) { 6706 PetscCall((*f)(A,rows,cols)); 6707 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6708 if (rows) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows)); 6709 if (cols) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols)); 6710 } 6711 PetscFunctionReturn(0); 6712 } 6713 6714 /*@C 6715 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6716 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6717 to complete the factorization. 6718 6719 Collective on Mat 6720 6721 Input Parameters: 6722 + mat - the matrix 6723 . row - row permutation 6724 . column - column permutation 6725 - info - structure containing 6726 $ levels - number of levels of fill. 6727 $ expected fill - as ratio of original fill. 6728 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6729 missing diagonal entries) 6730 6731 Output Parameters: 6732 . fact - new matrix that has been symbolically factored 6733 6734 Notes: 6735 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6736 6737 Most users should employ the simplified KSP interface for linear solvers 6738 instead of working directly with matrix algebra routines such as this. 6739 See, e.g., KSPCreate(). 6740 6741 Level: developer 6742 6743 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 6744 `MatGetOrdering()`, `MatFactorInfo` 6745 6746 Note: this uses the definition of level of fill as in Y. Saad, 2003 6747 6748 Developer Note: fortran interface is not autogenerated as the f90 6749 interface definition cannot be generated correctly [due to MatFactorInfo] 6750 6751 References: 6752 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6753 @*/ 6754 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6755 { 6756 PetscFunctionBegin; 6757 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6758 PetscValidType(mat,2); 6759 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 6760 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 6761 PetscValidPointer(info,5); 6762 PetscValidPointer(fact,1); 6763 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %" PetscInt_FMT,(PetscInt)info->levels); 6764 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6765 if (!fact->ops->ilufactorsymbolic) { 6766 MatSolverType stype; 6767 PetscCall(MatFactorGetSolverType(fact,&stype)); 6768 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype); 6769 } 6770 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6771 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6772 MatCheckPreallocated(mat,2); 6773 6774 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0)); 6775 PetscCall((fact->ops->ilufactorsymbolic)(fact,mat,row,col,info)); 6776 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0)); 6777 PetscFunctionReturn(0); 6778 } 6779 6780 /*@C 6781 MatICCFactorSymbolic - Performs symbolic incomplete 6782 Cholesky factorization for a symmetric matrix. Use 6783 MatCholeskyFactorNumeric() to complete the factorization. 6784 6785 Collective on Mat 6786 6787 Input Parameters: 6788 + mat - the matrix 6789 . perm - row and column permutation 6790 - info - structure containing 6791 $ levels - number of levels of fill. 6792 $ expected fill - as ratio of original fill. 6793 6794 Output Parameter: 6795 . fact - the factored matrix 6796 6797 Notes: 6798 Most users should employ the KSP interface for linear solvers 6799 instead of working directly with matrix algebra routines such as this. 6800 See, e.g., KSPCreate(). 6801 6802 Level: developer 6803 6804 .seealso: `MatCholeskyFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 6805 6806 Note: this uses the definition of level of fill as in Y. Saad, 2003 6807 6808 Developer Note: fortran interface is not autogenerated as the f90 6809 interface definition cannot be generated correctly [due to MatFactorInfo] 6810 6811 References: 6812 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6813 @*/ 6814 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6815 { 6816 PetscFunctionBegin; 6817 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6818 PetscValidType(mat,2); 6819 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 6820 PetscValidPointer(info,4); 6821 PetscValidPointer(fact,1); 6822 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6823 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %" PetscInt_FMT,(PetscInt) info->levels); 6824 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6825 if (!(fact)->ops->iccfactorsymbolic) { 6826 MatSolverType stype; 6827 PetscCall(MatFactorGetSolverType(fact,&stype)); 6828 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype); 6829 } 6830 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6831 MatCheckPreallocated(mat,2); 6832 6833 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6834 PetscCall((fact->ops->iccfactorsymbolic)(fact,mat,perm,info)); 6835 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6836 PetscFunctionReturn(0); 6837 } 6838 6839 /*@C 6840 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6841 points to an array of valid matrices, they may be reused to store the new 6842 submatrices. 6843 6844 Collective on Mat 6845 6846 Input Parameters: 6847 + mat - the matrix 6848 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6849 . irow, icol - index sets of rows and columns to extract 6850 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6851 6852 Output Parameter: 6853 . submat - the array of submatrices 6854 6855 Notes: 6856 MatCreateSubMatrices() can extract ONLY sequential submatrices 6857 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6858 to extract a parallel submatrix. 6859 6860 Some matrix types place restrictions on the row and column 6861 indices, such as that they be sorted or that they be equal to each other. 6862 6863 The index sets may not have duplicate entries. 6864 6865 When extracting submatrices from a parallel matrix, each processor can 6866 form a different submatrix by setting the rows and columns of its 6867 individual index sets according to the local submatrix desired. 6868 6869 When finished using the submatrices, the user should destroy 6870 them with MatDestroySubMatrices(). 6871 6872 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6873 original matrix has not changed from that last call to MatCreateSubMatrices(). 6874 6875 This routine creates the matrices in submat; you should NOT create them before 6876 calling it. It also allocates the array of matrix pointers submat. 6877 6878 For BAIJ matrices the index sets must respect the block structure, that is if they 6879 request one row/column in a block, they must request all rows/columns that are in 6880 that block. For example, if the block size is 2 you cannot request just row 0 and 6881 column 0. 6882 6883 Fortran Note: 6884 The Fortran interface is slightly different from that given below; it 6885 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6886 6887 Level: advanced 6888 6889 .seealso: `MatDestroySubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 6890 @*/ 6891 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6892 { 6893 PetscInt i; 6894 PetscBool eq; 6895 6896 PetscFunctionBegin; 6897 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6898 PetscValidType(mat,1); 6899 if (n) { 6900 PetscValidPointer(irow,3); 6901 for (i=0; i<n; i++) PetscValidHeaderSpecific(irow[i],IS_CLASSID,3); 6902 PetscValidPointer(icol,4); 6903 for (i=0; i<n; i++) PetscValidHeaderSpecific(icol[i],IS_CLASSID,4); 6904 } 6905 PetscValidPointer(submat,6); 6906 if (n && scall == MAT_REUSE_MATRIX) { 6907 PetscValidPointer(*submat,6); 6908 for (i=0; i<n; i++) PetscValidHeaderSpecific((*submat)[i],MAT_CLASSID,6); 6909 } 6910 PetscCheck(mat->ops->createsubmatrices,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6911 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6912 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6913 MatCheckPreallocated(mat,1); 6914 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 6915 PetscCall((*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat)); 6916 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 6917 for (i=0; i<n; i++) { 6918 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6919 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 6920 if (eq) { 6921 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 6922 } 6923 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6924 if (mat->boundtocpu && mat->bindingpropagates) { 6925 PetscCall(MatBindToCPU((*submat)[i],PETSC_TRUE)); 6926 PetscCall(MatSetBindingPropagates((*submat)[i],PETSC_TRUE)); 6927 } 6928 #endif 6929 } 6930 PetscFunctionReturn(0); 6931 } 6932 6933 /*@C 6934 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6935 6936 Collective on Mat 6937 6938 Input Parameters: 6939 + mat - the matrix 6940 . n - the number of submatrixes to be extracted 6941 . irow, icol - index sets of rows and columns to extract 6942 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6943 6944 Output Parameter: 6945 . submat - the array of submatrices 6946 6947 Level: advanced 6948 6949 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 6950 @*/ 6951 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6952 { 6953 PetscInt i; 6954 PetscBool eq; 6955 6956 PetscFunctionBegin; 6957 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6958 PetscValidType(mat,1); 6959 if (n) { 6960 PetscValidPointer(irow,3); 6961 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6962 PetscValidPointer(icol,4); 6963 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6964 } 6965 PetscValidPointer(submat,6); 6966 if (n && scall == MAT_REUSE_MATRIX) { 6967 PetscValidPointer(*submat,6); 6968 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6969 } 6970 PetscCheck(mat->ops->createsubmatricesmpi,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6971 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6972 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6973 MatCheckPreallocated(mat,1); 6974 6975 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 6976 PetscCall((*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat)); 6977 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 6978 for (i=0; i<n; i++) { 6979 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 6980 if (eq) { 6981 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 6982 } 6983 } 6984 PetscFunctionReturn(0); 6985 } 6986 6987 /*@C 6988 MatDestroyMatrices - Destroys an array of matrices. 6989 6990 Collective on Mat 6991 6992 Input Parameters: 6993 + n - the number of local matrices 6994 - mat - the matrices (note that this is a pointer to the array of matrices) 6995 6996 Level: advanced 6997 6998 Notes: 6999 Frees not only the matrices, but also the array that contains the matrices 7000 In Fortran will not free the array. 7001 7002 .seealso: `MatCreateSubMatrices()` `MatDestroySubMatrices()` 7003 @*/ 7004 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 7005 { 7006 PetscInt i; 7007 7008 PetscFunctionBegin; 7009 if (!*mat) PetscFunctionReturn(0); 7010 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7011 PetscValidPointer(mat,2); 7012 7013 for (i=0; i<n; i++) { 7014 PetscCall(MatDestroy(&(*mat)[i])); 7015 } 7016 7017 /* memory is allocated even if n = 0 */ 7018 PetscCall(PetscFree(*mat)); 7019 PetscFunctionReturn(0); 7020 } 7021 7022 /*@C 7023 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 7024 7025 Collective on Mat 7026 7027 Input Parameters: 7028 + n - the number of local matrices 7029 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 7030 sequence of MatCreateSubMatrices()) 7031 7032 Level: advanced 7033 7034 Notes: 7035 Frees not only the matrices, but also the array that contains the matrices 7036 In Fortran will not free the array. 7037 7038 .seealso: `MatCreateSubMatrices()` 7039 @*/ 7040 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 7041 { 7042 Mat mat0; 7043 7044 PetscFunctionBegin; 7045 if (!*mat) PetscFunctionReturn(0); 7046 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7047 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7048 PetscValidPointer(mat,2); 7049 7050 mat0 = (*mat)[0]; 7051 if (mat0 && mat0->ops->destroysubmatrices) { 7052 PetscCall((mat0->ops->destroysubmatrices)(n,mat)); 7053 } else { 7054 PetscCall(MatDestroyMatrices(n,mat)); 7055 } 7056 PetscFunctionReturn(0); 7057 } 7058 7059 /*@C 7060 MatGetSeqNonzeroStructure - Extracts the nonzero structure from a matrix and stores it, in its entirety, on each process 7061 7062 Collective on Mat 7063 7064 Input Parameters: 7065 . mat - the matrix 7066 7067 Output Parameter: 7068 . matstruct - the sequential matrix with the nonzero structure of mat 7069 7070 Level: intermediate 7071 7072 .seealso: `MatDestroySeqNonzeroStructure()`, `MatCreateSubMatrices()`, `MatDestroyMatrices()` 7073 @*/ 7074 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7075 { 7076 PetscFunctionBegin; 7077 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7078 PetscValidPointer(matstruct,2); 7079 7080 PetscValidType(mat,1); 7081 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7082 MatCheckPreallocated(mat,1); 7083 7084 PetscCheck(mat->ops->getseqnonzerostructure,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)mat)->type_name); 7085 PetscCall(PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7086 PetscCall((*mat->ops->getseqnonzerostructure)(mat,matstruct)); 7087 PetscCall(PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7088 PetscFunctionReturn(0); 7089 } 7090 7091 /*@C 7092 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7093 7094 Collective on Mat 7095 7096 Input Parameters: 7097 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7098 sequence of MatGetSequentialNonzeroStructure()) 7099 7100 Level: advanced 7101 7102 Notes: 7103 Frees not only the matrices, but also the array that contains the matrices 7104 7105 .seealso: `MatGetSeqNonzeroStructure()` 7106 @*/ 7107 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7108 { 7109 PetscFunctionBegin; 7110 PetscValidPointer(mat,1); 7111 PetscCall(MatDestroy(mat)); 7112 PetscFunctionReturn(0); 7113 } 7114 7115 /*@ 7116 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7117 replaces the index sets by larger ones that represent submatrices with 7118 additional overlap. 7119 7120 Collective on Mat 7121 7122 Input Parameters: 7123 + mat - the matrix 7124 . n - the number of index sets 7125 . is - the array of index sets (these index sets will changed during the call) 7126 - ov - the additional overlap requested 7127 7128 Options Database: 7129 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7130 7131 Level: developer 7132 7133 Developer Note: 7134 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. 7135 7136 .seealso: `MatCreateSubMatrices()` 7137 @*/ 7138 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7139 { 7140 PetscInt i,bs,cbs; 7141 7142 PetscFunctionBegin; 7143 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7144 PetscValidType(mat,1); 7145 PetscValidLogicalCollectiveInt(mat,n,2); 7146 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7147 if (n) { 7148 PetscValidPointer(is,3); 7149 for (i = 0; i < n; i++) PetscValidHeaderSpecific(is[i],IS_CLASSID,3); 7150 } 7151 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7152 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7153 MatCheckPreallocated(mat,1); 7154 7155 if (!ov || !n) PetscFunctionReturn(0); 7156 PetscCheck(mat->ops->increaseoverlap,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7157 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7158 PetscCall((*mat->ops->increaseoverlap)(mat,n,is,ov)); 7159 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7160 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 7161 if (bs == cbs) { 7162 for (i=0; i<n; i++) { 7163 PetscCall(ISSetBlockSize(is[i],bs)); 7164 } 7165 } 7166 PetscFunctionReturn(0); 7167 } 7168 7169 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7170 7171 /*@ 7172 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7173 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7174 additional overlap. 7175 7176 Collective on Mat 7177 7178 Input Parameters: 7179 + mat - the matrix 7180 . n - the number of index sets 7181 . is - the array of index sets (these index sets will changed during the call) 7182 - ov - the additional overlap requested 7183 7184 Options Database: 7185 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7186 7187 Level: developer 7188 7189 .seealso: `MatCreateSubMatrices()` 7190 @*/ 7191 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7192 { 7193 PetscInt i; 7194 7195 PetscFunctionBegin; 7196 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7197 PetscValidType(mat,1); 7198 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7199 if (n) { 7200 PetscValidPointer(is,3); 7201 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7202 } 7203 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7204 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7205 MatCheckPreallocated(mat,1); 7206 if (!ov) PetscFunctionReturn(0); 7207 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7208 for (i=0; i<n; i++) { 7209 PetscCall(MatIncreaseOverlapSplit_Single(mat,&is[i],ov)); 7210 } 7211 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7212 PetscFunctionReturn(0); 7213 } 7214 7215 /*@ 7216 MatGetBlockSize - Returns the matrix block size. 7217 7218 Not Collective 7219 7220 Input Parameter: 7221 . mat - the matrix 7222 7223 Output Parameter: 7224 . bs - block size 7225 7226 Notes: 7227 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7228 7229 If the block size has not been set yet this routine returns 1. 7230 7231 Level: intermediate 7232 7233 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSizes()` 7234 @*/ 7235 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7236 { 7237 PetscFunctionBegin; 7238 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7239 PetscValidIntPointer(bs,2); 7240 *bs = PetscAbs(mat->rmap->bs); 7241 PetscFunctionReturn(0); 7242 } 7243 7244 /*@ 7245 MatGetBlockSizes - Returns the matrix block row and column sizes. 7246 7247 Not Collective 7248 7249 Input Parameter: 7250 . mat - the matrix 7251 7252 Output Parameters: 7253 + rbs - row block size 7254 - cbs - column block size 7255 7256 Notes: 7257 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7258 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7259 7260 If a block size has not been set yet this routine returns 1. 7261 7262 Level: intermediate 7263 7264 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatSetBlockSizes()` 7265 @*/ 7266 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7267 { 7268 PetscFunctionBegin; 7269 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7270 if (rbs) PetscValidIntPointer(rbs,2); 7271 if (cbs) PetscValidIntPointer(cbs,3); 7272 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7273 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7274 PetscFunctionReturn(0); 7275 } 7276 7277 /*@ 7278 MatSetBlockSize - Sets the matrix block size. 7279 7280 Logically Collective on Mat 7281 7282 Input Parameters: 7283 + mat - the matrix 7284 - bs - block size 7285 7286 Notes: 7287 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7288 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7289 7290 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7291 is compatible with the matrix local sizes. 7292 7293 Level: intermediate 7294 7295 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()` 7296 @*/ 7297 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7298 { 7299 PetscFunctionBegin; 7300 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7301 PetscValidLogicalCollectiveInt(mat,bs,2); 7302 PetscCall(MatSetBlockSizes(mat,bs,bs)); 7303 PetscFunctionReturn(0); 7304 } 7305 7306 typedef struct { 7307 PetscInt n; 7308 IS *is; 7309 Mat *mat; 7310 PetscObjectState nonzerostate; 7311 Mat C; 7312 } EnvelopeData; 7313 7314 static PetscErrorCode EnvelopeDataDestroy(EnvelopeData *edata) 7315 { 7316 for (PetscInt i=0; i<edata->n; i++) { 7317 PetscCall(ISDestroy(&edata->is[i])); 7318 } 7319 PetscCall(PetscFree(edata->is)); 7320 PetscCall(PetscFree(edata)); 7321 return 0; 7322 } 7323 7324 /* 7325 MatComputeVariableBlockEnvelope - Given a matrix whose nonzeros are in blocks along the diagonal this computes and stores 7326 the sizes of these blocks in the matrix. An individual block may lie over several processes. 7327 7328 Collective on mat 7329 7330 Input Parameter: 7331 . mat - the matrix 7332 7333 Notes: 7334 There can be zeros within the blocks 7335 7336 The blocks can overlap between processes, including laying on more than two processes 7337 7338 */ 7339 static PetscErrorCode MatComputeVariableBlockEnvelope(Mat mat) 7340 { 7341 PetscInt n,*sizes,*starts,i = 0,env = 0, tbs = 0, lblocks = 0,rstart,II,ln = 0,cnt = 0,cstart,cend; 7342 PetscInt *diag,*odiag,sc; 7343 VecScatter scatter; 7344 PetscScalar *seqv; 7345 const PetscScalar *parv; 7346 const PetscInt *ia,*ja; 7347 PetscBool set,flag,done; 7348 Mat AA = mat,A; 7349 MPI_Comm comm; 7350 PetscMPIInt rank,size,tag; 7351 MPI_Status status; 7352 PetscContainer container; 7353 EnvelopeData *edata; 7354 Vec seq,par; 7355 IS isglobal; 7356 7357 PetscFunctionBegin; 7358 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7359 PetscCall(MatIsSymmetricKnown(mat,&set,&flag)); 7360 if (!set || !flag) { 7361 /* TOO: only needs nonzero structure of transpose */ 7362 PetscCall(MatTranspose(mat,MAT_INITIAL_MATRIX,&AA)); 7363 PetscCall(MatAXPY(AA,1.0,mat,DIFFERENT_NONZERO_PATTERN)); 7364 } 7365 PetscCall(MatAIJGetLocalMat(AA,&A)); 7366 PetscCall(MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7367 PetscCheck(done,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Unable to get IJ structure from matrix"); 7368 7369 PetscCall(MatGetLocalSize(mat,&n,NULL)); 7370 PetscCall(PetscObjectGetNewTag((PetscObject)mat,&tag)); 7371 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 7372 PetscCallMPI(MPI_Comm_size(comm,&size)); 7373 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 7374 7375 PetscCall(PetscMalloc2(n,&sizes,n,&starts)); 7376 7377 if (rank > 0) { 7378 PetscCallMPI(MPI_Recv(&env,1,MPIU_INT,rank-1,tag,comm,&status)); 7379 PetscCallMPI(MPI_Recv(&tbs,1,MPIU_INT,rank-1,tag,comm,&status)); 7380 } 7381 PetscCall(MatGetOwnershipRange(mat,&rstart,NULL)); 7382 for (i=0; i<n; i++) { 7383 env = PetscMax(env,ja[ia[i+1]-1]); 7384 II = rstart + i; 7385 if (env == II) { 7386 starts[lblocks] = tbs; 7387 sizes[lblocks++] = 1 + II - tbs; 7388 tbs = 1 + II; 7389 } 7390 } 7391 if (rank < size-1) { 7392 PetscCallMPI(MPI_Send(&env,1,MPIU_INT,rank+1,tag,comm)); 7393 PetscCallMPI(MPI_Send(&tbs,1,MPIU_INT,rank+1,tag,comm)); 7394 } 7395 7396 PetscCall(MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7397 if (!set || !flag) { 7398 PetscCall(MatDestroy(&AA)); 7399 } 7400 PetscCall(MatDestroy(&A)); 7401 7402 PetscCall(PetscNew(&edata)); 7403 PetscCall(MatGetNonzeroState(mat,&edata->nonzerostate)); 7404 edata->n = lblocks; 7405 /* create IS needed for extracting blocks from the original matrix */ 7406 PetscCall(PetscMalloc1(lblocks,&edata->is)); 7407 for (PetscInt i=0; i<lblocks; i++) { 7408 PetscCall(ISCreateStride(PETSC_COMM_SELF,sizes[i],starts[i],1,&edata->is[i])); 7409 } 7410 7411 /* Create the resulting inverse matrix structure with preallocation information */ 7412 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&edata->C)); 7413 PetscCall(MatSetSizes(edata->C,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 7414 PetscCall(MatSetBlockSizesFromMats(edata->C,mat,mat)); 7415 PetscCall(MatSetType(edata->C,MATAIJ)); 7416 7417 /* Communicate the start and end of each row, from each block to the correct rank */ 7418 /* TODO: Use PetscSF instead of VecScatter */ 7419 for (PetscInt i=0; i<lblocks; i++) ln += sizes[i]; 7420 PetscCall(VecCreateSeq(PETSC_COMM_SELF,2*ln,&seq)); 7421 PetscCall(VecGetArrayWrite(seq,&seqv)); 7422 for (PetscInt i=0; i<lblocks; i++) { 7423 for (PetscInt j=0; j<sizes[i]; j++) { 7424 seqv[cnt] = starts[i]; 7425 seqv[cnt+1] = starts[i] + sizes[i]; 7426 cnt += 2; 7427 } 7428 } 7429 PetscCall(VecRestoreArrayWrite(seq,&seqv)); 7430 PetscCallMPI(MPI_Scan(&cnt,&sc,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 7431 sc -= cnt; 7432 PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)mat),2*mat->rmap->n,2*mat->rmap->N,&par)); 7433 PetscCall(ISCreateStride(PETSC_COMM_SELF,cnt,sc,1,&isglobal)); 7434 PetscCall(VecScatterCreate(seq, NULL ,par, isglobal,&scatter)); 7435 PetscCall(ISDestroy(&isglobal)); 7436 PetscCall(VecScatterBegin(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7437 PetscCall(VecScatterEnd(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7438 PetscCall(VecScatterDestroy(&scatter)); 7439 PetscCall(VecDestroy(&seq)); 7440 PetscCall(MatGetOwnershipRangeColumn(mat,&cstart,&cend)); 7441 PetscCall(PetscMalloc2(mat->rmap->n,&diag,mat->rmap->n,&odiag)); 7442 PetscCall(VecGetArrayRead(par,&parv)); 7443 cnt = 0; 7444 PetscCall(MatGetSize(mat,NULL,&n)); 7445 for (PetscInt i=0; i<mat->rmap->n; i++) { 7446 PetscInt start,end,d = 0,od = 0; 7447 7448 start = (PetscInt)PetscRealPart(parv[cnt]); 7449 end = (PetscInt)PetscRealPart(parv[cnt+1]); 7450 cnt += 2; 7451 7452 if (start < cstart) {od += cstart - start + n - cend; d += cend - cstart;} 7453 else if (start < cend) {od += n - cend; d += cend - start;} 7454 else od += n - start; 7455 if (end <= cstart) {od -= cstart - end + n - cend; d -= cend - cstart;} 7456 else if (end < cend) {od -= n - cend; d -= cend - end;} 7457 else od -= n - end; 7458 7459 odiag[i] = od; 7460 diag[i] = d; 7461 } 7462 PetscCall(VecRestoreArrayRead(par,&parv)); 7463 PetscCall(VecDestroy(&par)); 7464 PetscCall(MatXAIJSetPreallocation(edata->C,mat->rmap->bs,diag,odiag,NULL,NULL)); 7465 PetscCall(PetscFree2(diag,odiag)); 7466 PetscCall(PetscFree2(sizes,starts)); 7467 7468 PetscCall(PetscContainerCreate(PETSC_COMM_SELF,&container)); 7469 PetscCall(PetscContainerSetPointer(container,edata)); 7470 PetscCall(PetscContainerSetUserDestroy(container,(PetscErrorCode (*)(void*))EnvelopeDataDestroy)); 7471 PetscCall(PetscObjectCompose((PetscObject)mat,"EnvelopeData",(PetscObject)container)); 7472 PetscCall(PetscObjectDereference((PetscObject)container)); 7473 PetscFunctionReturn(0); 7474 } 7475 7476 /*@ 7477 MatInvertVariableBlockEnvelope - set matrix C to be the inverted block diagonal of matrix A 7478 7479 Collective on Mat 7480 7481 Input Parameters: 7482 . A - the matrix 7483 7484 Output Parameters: 7485 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 7486 7487 Notes: 7488 For efficiency the matrix A should have all the nonzero entries clustered in smallish blocks along the diagonal. 7489 7490 Level: advanced 7491 7492 .seealso: MatInvertBlockDiagonal(), MatComputeBlockDiagonal() 7493 @*/ 7494 PetscErrorCode MatInvertVariableBlockEnvelope(Mat A,MatReuse reuse, Mat *C) 7495 { 7496 PetscContainer container; 7497 EnvelopeData *edata; 7498 PetscObjectState nonzerostate; 7499 7500 PetscFunctionBegin; 7501 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7502 if (!container) { 7503 PetscCall(MatComputeVariableBlockEnvelope(A)); 7504 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7505 } 7506 PetscCall(PetscContainerGetPointer(container,(void**)&edata)); 7507 PetscCall(MatGetNonzeroState(A,&nonzerostate)); 7508 PetscCheck(nonzerostate <= edata->nonzerostate,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot handle changes to matrix nonzero structure"); 7509 PetscCheck(reuse != MAT_REUSE_MATRIX || *C == edata->C,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C matrix must be the same as previously output"); 7510 7511 PetscCall(MatCreateSubMatrices(A,edata->n,edata->is,edata->is,MAT_INITIAL_MATRIX,&edata->mat)); 7512 *C = edata->C; 7513 7514 for (PetscInt i=0; i<edata->n; i++) { 7515 Mat D; 7516 PetscScalar *dvalues; 7517 7518 PetscCall(MatConvert(edata->mat[i], MATSEQDENSE,MAT_INITIAL_MATRIX,&D)); 7519 PetscCall(MatSetOption(*C,MAT_ROW_ORIENTED,PETSC_FALSE)); 7520 PetscCall(MatSeqDenseInvert(D)); 7521 PetscCall(MatDenseGetArray(D,&dvalues)); 7522 PetscCall(MatSetValuesIS(*C,edata->is[i],edata->is[i],dvalues,INSERT_VALUES)); 7523 PetscCall(MatDestroy(&D)); 7524 } 7525 PetscCall(MatDestroySubMatrices(edata->n,&edata->mat)); 7526 PetscCall(MatAssemblyBegin(*C,MAT_FINAL_ASSEMBLY)); 7527 PetscCall(MatAssemblyEnd(*C,MAT_FINAL_ASSEMBLY)); 7528 PetscFunctionReturn(0); 7529 } 7530 7531 /*@ 7532 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7533 7534 Logically Collective on Mat 7535 7536 Input Parameters: 7537 + mat - the matrix 7538 . nblocks - the number of blocks on this process, each block can only exist on a single process 7539 - bsizes - the block sizes 7540 7541 Notes: 7542 Currently used by PCVPBJACOBI for AIJ matrices 7543 7544 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. 7545 7546 Level: intermediate 7547 7548 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatGetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()`, `PCVPBJACOBI` 7549 @*/ 7550 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7551 { 7552 PetscInt i,ncnt = 0, nlocal; 7553 7554 PetscFunctionBegin; 7555 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7556 PetscCheck(nblocks >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7557 PetscCall(MatGetLocalSize(mat,&nlocal,NULL)); 7558 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7559 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); 7560 PetscCall(PetscFree(mat->bsizes)); 7561 mat->nblocks = nblocks; 7562 PetscCall(PetscMalloc1(nblocks,&mat->bsizes)); 7563 PetscCall(PetscArraycpy(mat->bsizes,bsizes,nblocks)); 7564 PetscFunctionReturn(0); 7565 } 7566 7567 /*@C 7568 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7569 7570 Logically Collective on Mat 7571 7572 Input Parameter: 7573 . mat - the matrix 7574 7575 Output Parameters: 7576 + nblocks - the number of blocks on this process 7577 - bsizes - the block sizes 7578 7579 Notes: Currently not supported from Fortran 7580 7581 Level: intermediate 7582 7583 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatSetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()` 7584 @*/ 7585 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7586 { 7587 PetscFunctionBegin; 7588 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7589 *nblocks = mat->nblocks; 7590 *bsizes = mat->bsizes; 7591 PetscFunctionReturn(0); 7592 } 7593 7594 /*@ 7595 MatSetBlockSizes - Sets the matrix block row and column sizes. 7596 7597 Logically Collective on Mat 7598 7599 Input Parameters: 7600 + mat - the matrix 7601 . rbs - row block size 7602 - cbs - column block size 7603 7604 Notes: 7605 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7606 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7607 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7608 7609 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7610 are compatible with the matrix local sizes. 7611 7612 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7613 7614 Level: intermediate 7615 7616 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatGetBlockSizes()` 7617 @*/ 7618 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7619 { 7620 PetscFunctionBegin; 7621 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7622 PetscValidLogicalCollectiveInt(mat,rbs,2); 7623 PetscValidLogicalCollectiveInt(mat,cbs,3); 7624 if (mat->ops->setblocksizes) PetscCall((*mat->ops->setblocksizes)(mat,rbs,cbs)); 7625 if (mat->rmap->refcnt) { 7626 ISLocalToGlobalMapping l2g = NULL; 7627 PetscLayout nmap = NULL; 7628 7629 PetscCall(PetscLayoutDuplicate(mat->rmap,&nmap)); 7630 if (mat->rmap->mapping) { 7631 PetscCall(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g)); 7632 } 7633 PetscCall(PetscLayoutDestroy(&mat->rmap)); 7634 mat->rmap = nmap; 7635 mat->rmap->mapping = l2g; 7636 } 7637 if (mat->cmap->refcnt) { 7638 ISLocalToGlobalMapping l2g = NULL; 7639 PetscLayout nmap = NULL; 7640 7641 PetscCall(PetscLayoutDuplicate(mat->cmap,&nmap)); 7642 if (mat->cmap->mapping) { 7643 PetscCall(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g)); 7644 } 7645 PetscCall(PetscLayoutDestroy(&mat->cmap)); 7646 mat->cmap = nmap; 7647 mat->cmap->mapping = l2g; 7648 } 7649 PetscCall(PetscLayoutSetBlockSize(mat->rmap,rbs)); 7650 PetscCall(PetscLayoutSetBlockSize(mat->cmap,cbs)); 7651 PetscFunctionReturn(0); 7652 } 7653 7654 /*@ 7655 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7656 7657 Logically Collective on Mat 7658 7659 Input Parameters: 7660 + mat - the matrix 7661 . fromRow - matrix from which to copy row block size 7662 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7663 7664 Level: developer 7665 7666 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()` 7667 @*/ 7668 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7669 { 7670 PetscFunctionBegin; 7671 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7672 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7673 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7674 if (fromRow->rmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs)); 7675 if (fromCol->cmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs)); 7676 PetscFunctionReturn(0); 7677 } 7678 7679 /*@ 7680 MatResidual - Default routine to calculate the residual. 7681 7682 Collective on Mat 7683 7684 Input Parameters: 7685 + mat - the matrix 7686 . b - the right-hand-side 7687 - x - the approximate solution 7688 7689 Output Parameter: 7690 . r - location to store the residual 7691 7692 Level: developer 7693 7694 .seealso: `PCMGSetResidual()` 7695 @*/ 7696 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7697 { 7698 PetscFunctionBegin; 7699 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7700 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7701 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7702 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7703 PetscValidType(mat,1); 7704 MatCheckPreallocated(mat,1); 7705 PetscCall(PetscLogEventBegin(MAT_Residual,mat,0,0,0)); 7706 if (!mat->ops->residual) { 7707 PetscCall(MatMult(mat,x,r)); 7708 PetscCall(VecAYPX(r,-1.0,b)); 7709 } else { 7710 PetscCall((*mat->ops->residual)(mat,b,x,r)); 7711 } 7712 PetscCall(PetscLogEventEnd(MAT_Residual,mat,0,0,0)); 7713 PetscFunctionReturn(0); 7714 } 7715 7716 /*@C 7717 MatGetRowIJ - Returns the compressed row storage i and j indices for the local rows of a sparse matrix 7718 7719 Collective on Mat 7720 7721 Input Parameters: 7722 + mat - the matrix 7723 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7724 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7725 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7726 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7727 always used. 7728 7729 Output Parameters: 7730 + n - number of local rows in the (possibly compressed) matrix 7731 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7732 . ja - the column indices 7733 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7734 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7735 7736 Level: developer 7737 7738 Notes: 7739 You CANNOT change any of the ia[] or ja[] values. 7740 7741 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7742 7743 Fortran Notes: 7744 In Fortran use 7745 $ 7746 $ PetscInt ia(1), ja(1) 7747 $ PetscOffset iia, jja 7748 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7749 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7750 7751 or 7752 $ 7753 $ PetscInt, pointer :: ia(:),ja(:) 7754 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7755 $ ! Access the ith and jth entries via ia(i) and ja(j) 7756 7757 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()`, `MatSeqAIJGetArray()` 7758 @*/ 7759 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7760 { 7761 PetscFunctionBegin; 7762 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7763 PetscValidType(mat,1); 7764 if (n) PetscValidIntPointer(n,5); 7765 if (ia) PetscValidPointer(ia,6); 7766 if (ja) PetscValidPointer(ja,7); 7767 if (done) PetscValidBoolPointer(done,8); 7768 MatCheckPreallocated(mat,1); 7769 if (!mat->ops->getrowij && done) *done = PETSC_FALSE; 7770 else { 7771 if (done) *done = PETSC_TRUE; 7772 PetscCall(PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0)); 7773 PetscCall((*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7774 PetscCall(PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0)); 7775 } 7776 PetscFunctionReturn(0); 7777 } 7778 7779 /*@C 7780 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7781 7782 Collective on Mat 7783 7784 Input Parameters: 7785 + mat - the matrix 7786 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7787 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7788 symmetrized 7789 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7790 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7791 always used. 7792 . n - number of columns in the (possibly compressed) matrix 7793 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7794 - ja - the row indices 7795 7796 Output Parameters: 7797 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7798 7799 Level: developer 7800 7801 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7802 @*/ 7803 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7804 { 7805 PetscFunctionBegin; 7806 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7807 PetscValidType(mat,1); 7808 PetscValidIntPointer(n,5); 7809 if (ia) PetscValidPointer(ia,6); 7810 if (ja) PetscValidPointer(ja,7); 7811 PetscValidBoolPointer(done,8); 7812 MatCheckPreallocated(mat,1); 7813 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7814 else { 7815 *done = PETSC_TRUE; 7816 PetscCall((*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7817 } 7818 PetscFunctionReturn(0); 7819 } 7820 7821 /*@C 7822 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7823 MatGetRowIJ(). 7824 7825 Collective on Mat 7826 7827 Input Parameters: 7828 + mat - the matrix 7829 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7830 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7831 symmetrized 7832 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7833 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7834 always used. 7835 . n - size of (possibly compressed) matrix 7836 . ia - the row pointers 7837 - ja - the column indices 7838 7839 Output Parameters: 7840 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7841 7842 Note: 7843 This routine zeros out n, ia, and ja. This is to prevent accidental 7844 us of the array after it has been restored. If you pass NULL, it will 7845 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7846 7847 Level: developer 7848 7849 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7850 @*/ 7851 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7852 { 7853 PetscFunctionBegin; 7854 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7855 PetscValidType(mat,1); 7856 if (ia) PetscValidPointer(ia,6); 7857 if (ja) PetscValidPointer(ja,7); 7858 if (done) PetscValidBoolPointer(done,8); 7859 MatCheckPreallocated(mat,1); 7860 7861 if (!mat->ops->restorerowij && done) *done = PETSC_FALSE; 7862 else { 7863 if (done) *done = PETSC_TRUE; 7864 PetscCall((*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7865 if (n) *n = 0; 7866 if (ia) *ia = NULL; 7867 if (ja) *ja = NULL; 7868 } 7869 PetscFunctionReturn(0); 7870 } 7871 7872 /*@C 7873 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7874 MatGetColumnIJ(). 7875 7876 Collective on Mat 7877 7878 Input Parameters: 7879 + mat - the matrix 7880 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7881 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7882 symmetrized 7883 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7884 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7885 always used. 7886 7887 Output Parameters: 7888 + n - size of (possibly compressed) matrix 7889 . ia - the column pointers 7890 . ja - the row indices 7891 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7892 7893 Level: developer 7894 7895 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()` 7896 @*/ 7897 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7898 { 7899 PetscFunctionBegin; 7900 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7901 PetscValidType(mat,1); 7902 if (ia) PetscValidPointer(ia,6); 7903 if (ja) PetscValidPointer(ja,7); 7904 PetscValidBoolPointer(done,8); 7905 MatCheckPreallocated(mat,1); 7906 7907 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7908 else { 7909 *done = PETSC_TRUE; 7910 PetscCall((*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7911 if (n) *n = 0; 7912 if (ia) *ia = NULL; 7913 if (ja) *ja = NULL; 7914 } 7915 PetscFunctionReturn(0); 7916 } 7917 7918 /*@C 7919 MatColoringPatch -Used inside matrix coloring routines that 7920 use MatGetRowIJ() and/or MatGetColumnIJ(). 7921 7922 Collective on Mat 7923 7924 Input Parameters: 7925 + mat - the matrix 7926 . ncolors - max color value 7927 . n - number of entries in colorarray 7928 - colorarray - array indicating color for each column 7929 7930 Output Parameters: 7931 . iscoloring - coloring generated using colorarray information 7932 7933 Level: developer 7934 7935 .seealso: `MatGetRowIJ()`, `MatGetColumnIJ()` 7936 7937 @*/ 7938 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7939 { 7940 PetscFunctionBegin; 7941 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7942 PetscValidType(mat,1); 7943 PetscValidIntPointer(colorarray,4); 7944 PetscValidPointer(iscoloring,5); 7945 MatCheckPreallocated(mat,1); 7946 7947 if (!mat->ops->coloringpatch) { 7948 PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring)); 7949 } else { 7950 PetscCall((*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring)); 7951 } 7952 PetscFunctionReturn(0); 7953 } 7954 7955 /*@ 7956 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7957 7958 Logically Collective on Mat 7959 7960 Input Parameter: 7961 . mat - the factored matrix to be reset 7962 7963 Notes: 7964 This routine should be used only with factored matrices formed by in-place 7965 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7966 format). This option can save memory, for example, when solving nonlinear 7967 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7968 ILU(0) preconditioner. 7969 7970 Note that one can specify in-place ILU(0) factorization by calling 7971 .vb 7972 PCType(pc,PCILU); 7973 PCFactorSeUseInPlace(pc); 7974 .ve 7975 or by using the options -pc_type ilu -pc_factor_in_place 7976 7977 In-place factorization ILU(0) can also be used as a local 7978 solver for the blocks within the block Jacobi or additive Schwarz 7979 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7980 for details on setting local solver options. 7981 7982 Most users should employ the simplified KSP interface for linear solvers 7983 instead of working directly with matrix algebra routines such as this. 7984 See, e.g., KSPCreate(). 7985 7986 Level: developer 7987 7988 .seealso: `PCFactorSetUseInPlace()`, `PCFactorGetUseInPlace()` 7989 7990 @*/ 7991 PetscErrorCode MatSetUnfactored(Mat mat) 7992 { 7993 PetscFunctionBegin; 7994 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7995 PetscValidType(mat,1); 7996 MatCheckPreallocated(mat,1); 7997 mat->factortype = MAT_FACTOR_NONE; 7998 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7999 PetscCall((*mat->ops->setunfactored)(mat)); 8000 PetscFunctionReturn(0); 8001 } 8002 8003 /*MC 8004 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 8005 8006 Synopsis: 8007 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8008 8009 Not collective 8010 8011 Input Parameter: 8012 . x - matrix 8013 8014 Output Parameters: 8015 + xx_v - the Fortran90 pointer to the array 8016 - ierr - error code 8017 8018 Example of Usage: 8019 .vb 8020 PetscScalar, pointer xx_v(:,:) 8021 .... 8022 call MatDenseGetArrayF90(x,xx_v,ierr) 8023 a = xx_v(3) 8024 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8025 .ve 8026 8027 Level: advanced 8028 8029 .seealso: `MatDenseRestoreArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJGetArrayF90()` 8030 8031 M*/ 8032 8033 /*MC 8034 MatDenseRestoreArrayF90 - Restores a matrix array that has been 8035 accessed with MatDenseGetArrayF90(). 8036 8037 Synopsis: 8038 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8039 8040 Not collective 8041 8042 Input Parameters: 8043 + x - matrix 8044 - xx_v - the Fortran90 pointer to the array 8045 8046 Output Parameter: 8047 . ierr - error code 8048 8049 Example of Usage: 8050 .vb 8051 PetscScalar, pointer xx_v(:,:) 8052 .... 8053 call MatDenseGetArrayF90(x,xx_v,ierr) 8054 a = xx_v(3) 8055 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8056 .ve 8057 8058 Level: advanced 8059 8060 .seealso: `MatDenseGetArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJRestoreArrayF90()` 8061 8062 M*/ 8063 8064 /*MC 8065 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 8066 8067 Synopsis: 8068 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8069 8070 Not collective 8071 8072 Input Parameter: 8073 . x - matrix 8074 8075 Output Parameters: 8076 + xx_v - the Fortran90 pointer to the array 8077 - ierr - error code 8078 8079 Example of Usage: 8080 .vb 8081 PetscScalar, pointer xx_v(:) 8082 .... 8083 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8084 a = xx_v(3) 8085 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8086 .ve 8087 8088 Level: advanced 8089 8090 .seealso: `MatSeqAIJRestoreArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseGetArrayF90()` 8091 8092 M*/ 8093 8094 /*MC 8095 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 8096 accessed with MatSeqAIJGetArrayF90(). 8097 8098 Synopsis: 8099 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8100 8101 Not collective 8102 8103 Input Parameters: 8104 + x - matrix 8105 - xx_v - the Fortran90 pointer to the array 8106 8107 Output Parameter: 8108 . ierr - error code 8109 8110 Example of Usage: 8111 .vb 8112 PetscScalar, pointer xx_v(:) 8113 .... 8114 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8115 a = xx_v(3) 8116 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8117 .ve 8118 8119 Level: advanced 8120 8121 .seealso: `MatSeqAIJGetArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseRestoreArrayF90()` 8122 8123 M*/ 8124 8125 /*@ 8126 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 8127 as the original matrix. 8128 8129 Collective on Mat 8130 8131 Input Parameters: 8132 + mat - the original matrix 8133 . isrow - parallel IS containing the rows this processor should obtain 8134 . 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. 8135 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8136 8137 Output Parameter: 8138 . newmat - the new submatrix, of the same type as the old 8139 8140 Level: advanced 8141 8142 Notes: 8143 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 8144 8145 Some matrix types place restrictions on the row and column indices, such 8146 as that they be sorted or that they be equal to each other. 8147 8148 The index sets may not have duplicate entries. 8149 8150 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 8151 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 8152 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 8153 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 8154 you are finished using it. 8155 8156 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8157 the input matrix. 8158 8159 If iscol is NULL then all columns are obtained (not supported in Fortran). 8160 8161 Example usage: 8162 Consider the following 8x8 matrix with 34 non-zero values, that is 8163 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8164 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8165 as follows: 8166 8167 .vb 8168 1 2 0 | 0 3 0 | 0 4 8169 Proc0 0 5 6 | 7 0 0 | 8 0 8170 9 0 10 | 11 0 0 | 12 0 8171 ------------------------------------- 8172 13 0 14 | 15 16 17 | 0 0 8173 Proc1 0 18 0 | 19 20 21 | 0 0 8174 0 0 0 | 22 23 0 | 24 0 8175 ------------------------------------- 8176 Proc2 25 26 27 | 0 0 28 | 29 0 8177 30 0 0 | 31 32 33 | 0 34 8178 .ve 8179 8180 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8181 8182 .vb 8183 2 0 | 0 3 0 | 0 8184 Proc0 5 6 | 7 0 0 | 8 8185 ------------------------------- 8186 Proc1 18 0 | 19 20 21 | 0 8187 ------------------------------- 8188 Proc2 26 27 | 0 0 28 | 29 8189 0 0 | 31 32 33 | 0 8190 .ve 8191 8192 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatricesMPI()`, `MatCreateSubMatrixVirtual()`, `MatSubMatrixVirtualUpdate()` 8193 @*/ 8194 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 8195 { 8196 PetscMPIInt size; 8197 Mat *local; 8198 IS iscoltmp; 8199 PetscBool flg; 8200 8201 PetscFunctionBegin; 8202 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8203 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 8204 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 8205 PetscValidPointer(newmat,5); 8206 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 8207 PetscValidType(mat,1); 8208 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8209 PetscCheck(cll != MAT_IGNORE_MATRIX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 8210 8211 MatCheckPreallocated(mat,1); 8212 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8213 8214 if (!iscol || isrow == iscol) { 8215 PetscBool stride; 8216 PetscMPIInt grabentirematrix = 0,grab; 8217 PetscCall(PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride)); 8218 if (stride) { 8219 PetscInt first,step,n,rstart,rend; 8220 PetscCall(ISStrideGetInfo(isrow,&first,&step)); 8221 if (step == 1) { 8222 PetscCall(MatGetOwnershipRange(mat,&rstart,&rend)); 8223 if (rstart == first) { 8224 PetscCall(ISGetLocalSize(isrow,&n)); 8225 if (n == rend-rstart) { 8226 grabentirematrix = 1; 8227 } 8228 } 8229 } 8230 } 8231 PetscCall(MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat))); 8232 if (grab) { 8233 PetscCall(PetscInfo(mat,"Getting entire matrix as submatrix\n")); 8234 if (cll == MAT_INITIAL_MATRIX) { 8235 *newmat = mat; 8236 PetscCall(PetscObjectReference((PetscObject)mat)); 8237 } 8238 PetscFunctionReturn(0); 8239 } 8240 } 8241 8242 if (!iscol) { 8243 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp)); 8244 } else { 8245 iscoltmp = iscol; 8246 } 8247 8248 /* if original matrix is on just one processor then use submatrix generated */ 8249 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8250 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat)); 8251 goto setproperties; 8252 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8253 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local)); 8254 *newmat = *local; 8255 PetscCall(PetscFree(local)); 8256 goto setproperties; 8257 } else if (!mat->ops->createsubmatrix) { 8258 /* Create a new matrix type that implements the operation using the full matrix */ 8259 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8260 switch (cll) { 8261 case MAT_INITIAL_MATRIX: 8262 PetscCall(MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat)); 8263 break; 8264 case MAT_REUSE_MATRIX: 8265 PetscCall(MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp)); 8266 break; 8267 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8268 } 8269 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8270 goto setproperties; 8271 } 8272 8273 PetscCheck(mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8274 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8275 PetscCall((*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat)); 8276 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8277 8278 setproperties: 8279 PetscCall(ISEqualUnsorted(isrow,iscoltmp,&flg)); 8280 if (flg) PetscCall(MatPropagateSymmetryOptions(mat,*newmat)); 8281 if (!iscol) PetscCall(ISDestroy(&iscoltmp)); 8282 if (*newmat && cll == MAT_INITIAL_MATRIX) PetscCall(PetscObjectStateIncrease((PetscObject)*newmat)); 8283 PetscFunctionReturn(0); 8284 } 8285 8286 /*@ 8287 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8288 8289 Not Collective 8290 8291 Input Parameters: 8292 + A - the matrix we wish to propagate options from 8293 - B - the matrix we wish to propagate options to 8294 8295 Level: beginner 8296 8297 Notes: 8298 Propagates the options associated to `MAT_SYMMETRY_ETERNAL`, `MAT_STRUCTURALLY_SYMMETRIC`, `MAT_HERMITIAN`, `MAT_SPD`, `MAT_SYMMETRIC`, and `MAT_STRUCTURAL_SYMMETRY_ETERNAL` 8299 8300 .seealso: `MatSetOption()`, `MatIsSymmetricKnown()`, `MatIsSPDKnown()`, `MatIsHermitianKnown()`, MatIsStructurallySymmetricKnown()` 8301 @*/ 8302 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) 8303 { 8304 PetscFunctionBegin; 8305 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8306 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8307 B->symmetry_eternal = A->symmetry_eternal; 8308 B->structural_symmetry_eternal = A->structural_symmetry_eternal; 8309 B->symmetric = A->symmetric; 8310 B->structurally_symmetric = A->structurally_symmetric; 8311 B->spd = A->spd; 8312 B->hermitian = A->hermitian; 8313 PetscFunctionReturn(0); 8314 } 8315 8316 /*@ 8317 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8318 used during the assembly process to store values that belong to 8319 other processors. 8320 8321 Not Collective 8322 8323 Input Parameters: 8324 + mat - the matrix 8325 . size - the initial size of the stash. 8326 - bsize - the initial size of the block-stash(if used). 8327 8328 Options Database Keys: 8329 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8330 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8331 8332 Level: intermediate 8333 8334 Notes: 8335 The block-stash is used for values set with MatSetValuesBlocked() while 8336 the stash is used for values set with MatSetValues() 8337 8338 Run with the option -info and look for output of the form 8339 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8340 to determine the appropriate value, MM, to use for size and 8341 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8342 to determine the value, BMM to use for bsize 8343 8344 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashGetInfo()` 8345 8346 @*/ 8347 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8348 { 8349 PetscFunctionBegin; 8350 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8351 PetscValidType(mat,1); 8352 PetscCall(MatStashSetInitialSize_Private(&mat->stash,size)); 8353 PetscCall(MatStashSetInitialSize_Private(&mat->bstash,bsize)); 8354 PetscFunctionReturn(0); 8355 } 8356 8357 /*@ 8358 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8359 the matrix 8360 8361 Neighbor-wise Collective on Mat 8362 8363 Input Parameters: 8364 + mat - the matrix 8365 . x,y - the vectors 8366 - w - where the result is stored 8367 8368 Level: intermediate 8369 8370 Notes: 8371 w may be the same vector as y. 8372 8373 This allows one to use either the restriction or interpolation (its transpose) 8374 matrix to do the interpolation 8375 8376 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8377 8378 @*/ 8379 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8380 { 8381 PetscInt M,N,Ny; 8382 8383 PetscFunctionBegin; 8384 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8385 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8386 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8387 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8388 PetscCall(MatGetSize(A,&M,&N)); 8389 PetscCall(VecGetSize(y,&Ny)); 8390 if (M == Ny) { 8391 PetscCall(MatMultAdd(A,x,y,w)); 8392 } else { 8393 PetscCall(MatMultTransposeAdd(A,x,y,w)); 8394 } 8395 PetscFunctionReturn(0); 8396 } 8397 8398 /*@ 8399 MatInterpolate - y = A*x or A'*x depending on the shape of 8400 the matrix 8401 8402 Neighbor-wise Collective on Mat 8403 8404 Input Parameters: 8405 + mat - the matrix 8406 - x,y - the vectors 8407 8408 Level: intermediate 8409 8410 Notes: 8411 This allows one to use either the restriction or interpolation (its transpose) 8412 matrix to do the interpolation 8413 8414 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8415 8416 @*/ 8417 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8418 { 8419 PetscInt M,N,Ny; 8420 8421 PetscFunctionBegin; 8422 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8423 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8424 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8425 PetscCall(MatGetSize(A,&M,&N)); 8426 PetscCall(VecGetSize(y,&Ny)); 8427 if (M == Ny) { 8428 PetscCall(MatMult(A,x,y)); 8429 } else { 8430 PetscCall(MatMultTranspose(A,x,y)); 8431 } 8432 PetscFunctionReturn(0); 8433 } 8434 8435 /*@ 8436 MatRestrict - y = A*x or A'*x 8437 8438 Neighbor-wise Collective on Mat 8439 8440 Input Parameters: 8441 + mat - the matrix 8442 - x,y - the vectors 8443 8444 Level: intermediate 8445 8446 Notes: 8447 This allows one to use either the restriction or interpolation (its transpose) 8448 matrix to do the restriction 8449 8450 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatInterpolate()` 8451 8452 @*/ 8453 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8454 { 8455 PetscInt M,N,Ny; 8456 8457 PetscFunctionBegin; 8458 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8459 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8460 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8461 PetscCall(MatGetSize(A,&M,&N)); 8462 PetscCall(VecGetSize(y,&Ny)); 8463 if (M == Ny) { 8464 PetscCall(MatMult(A,x,y)); 8465 } else { 8466 PetscCall(MatMultTranspose(A,x,y)); 8467 } 8468 PetscFunctionReturn(0); 8469 } 8470 8471 /*@ 8472 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8473 8474 Neighbor-wise Collective on Mat 8475 8476 Input Parameters: 8477 + mat - the matrix 8478 - w, x - the input dense matrices 8479 8480 Output Parameters: 8481 . y - the output dense matrix 8482 8483 Level: intermediate 8484 8485 Notes: 8486 This allows one to use either the restriction or interpolation (its transpose) 8487 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8488 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8489 8490 .seealso: `MatInterpolateAdd()`, `MatMatInterpolate()`, `MatMatRestrict()` 8491 8492 @*/ 8493 PetscErrorCode MatMatInterpolateAdd(Mat A,Mat x,Mat w,Mat *y) 8494 { 8495 PetscInt M,N,Mx,Nx,Mo,My = 0,Ny = 0; 8496 PetscBool trans = PETSC_TRUE; 8497 MatReuse reuse = MAT_INITIAL_MATRIX; 8498 8499 PetscFunctionBegin; 8500 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8501 PetscValidHeaderSpecific(x,MAT_CLASSID,2); 8502 PetscValidType(x,2); 8503 if (w) PetscValidHeaderSpecific(w,MAT_CLASSID,3); 8504 if (*y) PetscValidHeaderSpecific(*y,MAT_CLASSID,4); 8505 PetscCall(MatGetSize(A,&M,&N)); 8506 PetscCall(MatGetSize(x,&Mx,&Nx)); 8507 if (N == Mx) trans = PETSC_FALSE; 8508 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); 8509 Mo = trans ? N : M; 8510 if (*y) { 8511 PetscCall(MatGetSize(*y,&My,&Ny)); 8512 if (Mo == My && Nx == Ny) { reuse = MAT_REUSE_MATRIX; } 8513 else { 8514 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); 8515 PetscCall(MatDestroy(y)); 8516 } 8517 } 8518 8519 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8520 PetscBool flg; 8521 8522 PetscCall(PetscObjectQuery((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject*)&w)); 8523 if (w) { 8524 PetscInt My,Ny,Mw,Nw; 8525 8526 PetscCall(PetscObjectTypeCompare((PetscObject)*y,((PetscObject)w)->type_name,&flg)); 8527 PetscCall(MatGetSize(*y,&My,&Ny)); 8528 PetscCall(MatGetSize(w,&Mw,&Nw)); 8529 if (!flg || My != Mw || Ny != Nw) w = NULL; 8530 } 8531 if (!w) { 8532 PetscCall(MatDuplicate(*y,MAT_COPY_VALUES,&w)); 8533 PetscCall(PetscObjectCompose((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject)w)); 8534 PetscCall(PetscLogObjectParent((PetscObject)*y,(PetscObject)w)); 8535 PetscCall(PetscObjectDereference((PetscObject)w)); 8536 } else { 8537 PetscCall(MatCopy(*y,w,UNKNOWN_NONZERO_PATTERN)); 8538 } 8539 } 8540 if (!trans) { 8541 PetscCall(MatMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8542 } else { 8543 PetscCall(MatTransposeMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8544 } 8545 if (w) PetscCall(MatAXPY(*y,1.0,w,UNKNOWN_NONZERO_PATTERN)); 8546 PetscFunctionReturn(0); 8547 } 8548 8549 /*@ 8550 MatMatInterpolate - Y = A*X or A'*X 8551 8552 Neighbor-wise Collective on Mat 8553 8554 Input Parameters: 8555 + mat - the matrix 8556 - x - the input dense matrix 8557 8558 Output Parameters: 8559 . y - the output dense matrix 8560 8561 Level: intermediate 8562 8563 Notes: 8564 This allows one to use either the restriction or interpolation (its transpose) 8565 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8566 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8567 8568 .seealso: `MatInterpolate()`, `MatRestrict()`, `MatMatRestrict()` 8569 8570 @*/ 8571 PetscErrorCode MatMatInterpolate(Mat A,Mat x,Mat *y) 8572 { 8573 PetscFunctionBegin; 8574 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8575 PetscFunctionReturn(0); 8576 } 8577 8578 /*@ 8579 MatMatRestrict - Y = A*X or A'*X 8580 8581 Neighbor-wise Collective on Mat 8582 8583 Input Parameters: 8584 + mat - the matrix 8585 - x - the input dense matrix 8586 8587 Output Parameters: 8588 . y - the output dense matrix 8589 8590 Level: intermediate 8591 8592 Notes: 8593 This allows one to use either the restriction or interpolation (its transpose) 8594 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8595 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8596 8597 .seealso: `MatRestrict()`, `MatInterpolate()`, `MatMatInterpolate()` 8598 @*/ 8599 PetscErrorCode MatMatRestrict(Mat A,Mat x,Mat *y) 8600 { 8601 PetscFunctionBegin; 8602 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8603 PetscFunctionReturn(0); 8604 } 8605 8606 /*@ 8607 MatGetNullSpace - retrieves the null space of a matrix. 8608 8609 Logically Collective on Mat 8610 8611 Input Parameters: 8612 + mat - the matrix 8613 - nullsp - the null space object 8614 8615 Level: developer 8616 8617 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetNullSpace()` 8618 @*/ 8619 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8620 { 8621 PetscFunctionBegin; 8622 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8623 PetscValidPointer(nullsp,2); 8624 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8625 PetscFunctionReturn(0); 8626 } 8627 8628 /*@ 8629 MatSetNullSpace - attaches a null space to a matrix. 8630 8631 Logically Collective on Mat 8632 8633 Input Parameters: 8634 + mat - the matrix 8635 - nullsp - the null space object 8636 8637 Level: advanced 8638 8639 Notes: 8640 This null space is used by the KSP linear solvers to solve singular systems. 8641 8642 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 8643 8644 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 8645 to zero but the linear system will still be solved in a least squares sense. 8646 8647 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8648 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). 8649 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 8650 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 8651 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). 8652 This \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix. 8653 8654 If the matrix is known to be symmetric because it is an SBAIJ matrix or one as called MatSetOption(mat,MAT_SYMMETRIC or MAT_SYMMETRY_ETERNAL,PETSC_TRUE); this 8655 routine also automatically calls MatSetTransposeNullSpace(). 8656 8657 The user should call `MatNullSpaceDestroy()`. 8658 8659 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetTransposeNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, 8660 `KSPSetPCSide()` 8661 @*/ 8662 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8663 { 8664 PetscFunctionBegin; 8665 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8666 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8667 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8668 PetscCall(MatNullSpaceDestroy(&mat->nullsp)); 8669 mat->nullsp = nullsp; 8670 if (mat->symmetric == PETSC_BOOL3_TRUE) { 8671 PetscCall(MatSetTransposeNullSpace(mat,nullsp)); 8672 } 8673 PetscFunctionReturn(0); 8674 } 8675 8676 /*@ 8677 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8678 8679 Logically Collective on Mat 8680 8681 Input Parameters: 8682 + mat - the matrix 8683 - nullsp - the null space object 8684 8685 Level: developer 8686 8687 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetTransposeNullSpace()`, `MatSetNullSpace()`, `MatGetNullSpace()` 8688 @*/ 8689 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8690 { 8691 PetscFunctionBegin; 8692 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8693 PetscValidType(mat,1); 8694 PetscValidPointer(nullsp,2); 8695 *nullsp = (mat->symmetric == PETSC_BOOL3_TRUE && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8696 PetscFunctionReturn(0); 8697 } 8698 8699 /*@ 8700 MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix 8701 8702 Logically Collective on Mat 8703 8704 Input Parameters: 8705 + mat - the matrix 8706 - nullsp - the null space object 8707 8708 Level: advanced 8709 8710 Notes: 8711 This allows solving singular linear systems defined by the transpose of the matrix using KSP solvers with left preconditioning. 8712 8713 See MatSetNullSpace() 8714 8715 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, `KSPSetPCSide()` 8716 @*/ 8717 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8718 { 8719 PetscFunctionBegin; 8720 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8721 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8722 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8723 PetscCall(MatNullSpaceDestroy(&mat->transnullsp)); 8724 mat->transnullsp = nullsp; 8725 PetscFunctionReturn(0); 8726 } 8727 8728 /*@ 8729 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8730 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8731 8732 Logically Collective on Mat 8733 8734 Input Parameters: 8735 + mat - the matrix 8736 - nullsp - the null space object 8737 8738 Level: advanced 8739 8740 Notes: 8741 Overwrites any previous near null space that may have been attached 8742 8743 You can remove the null space by calling this routine with an nullsp of NULL 8744 8745 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNullSpace()`, `MatNullSpaceCreateRigidBody()`, `MatGetNearNullSpace()` 8746 @*/ 8747 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8748 { 8749 PetscFunctionBegin; 8750 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8751 PetscValidType(mat,1); 8752 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8753 MatCheckPreallocated(mat,1); 8754 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8755 PetscCall(MatNullSpaceDestroy(&mat->nearnullsp)); 8756 mat->nearnullsp = nullsp; 8757 PetscFunctionReturn(0); 8758 } 8759 8760 /*@ 8761 MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace() 8762 8763 Not Collective 8764 8765 Input Parameter: 8766 . mat - the matrix 8767 8768 Output Parameter: 8769 . nullsp - the null space object, NULL if not set 8770 8771 Level: developer 8772 8773 .seealso: `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatNullSpaceCreate()` 8774 @*/ 8775 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8776 { 8777 PetscFunctionBegin; 8778 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8779 PetscValidType(mat,1); 8780 PetscValidPointer(nullsp,2); 8781 MatCheckPreallocated(mat,1); 8782 *nullsp = mat->nearnullsp; 8783 PetscFunctionReturn(0); 8784 } 8785 8786 /*@C 8787 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8788 8789 Collective on Mat 8790 8791 Input Parameters: 8792 + mat - the matrix 8793 . row - row/column permutation 8794 . fill - expected fill factor >= 1.0 8795 - level - level of fill, for ICC(k) 8796 8797 Notes: 8798 Probably really in-place only when level of fill is zero, otherwise allocates 8799 new space to store factored matrix and deletes previous memory. 8800 8801 Most users should employ the simplified KSP interface for linear solvers 8802 instead of working directly with matrix algebra routines such as this. 8803 See, e.g., KSPCreate(). 8804 8805 Level: developer 8806 8807 .seealso: `MatICCFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 8808 8809 Developer Note: fortran interface is not autogenerated as the f90 8810 interface definition cannot be generated correctly [due to MatFactorInfo] 8811 8812 @*/ 8813 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8814 { 8815 PetscFunctionBegin; 8816 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8817 PetscValidType(mat,1); 8818 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8819 PetscValidPointer(info,3); 8820 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8821 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8822 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8823 PetscCheck(mat->ops->iccfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8824 MatCheckPreallocated(mat,1); 8825 PetscCall((*mat->ops->iccfactor)(mat,row,info)); 8826 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8827 PetscFunctionReturn(0); 8828 } 8829 8830 /*@ 8831 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8832 ghosted ones. 8833 8834 Not Collective 8835 8836 Input Parameters: 8837 + mat - the matrix 8838 - diag - the diagonal values, including ghost ones 8839 8840 Level: developer 8841 8842 Notes: 8843 Works only for MPIAIJ and MPIBAIJ matrices 8844 8845 .seealso: `MatDiagonalScale()` 8846 @*/ 8847 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8848 { 8849 PetscMPIInt size; 8850 8851 PetscFunctionBegin; 8852 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8853 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8854 PetscValidType(mat,1); 8855 8856 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8857 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 8858 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8859 if (size == 1) { 8860 PetscInt n,m; 8861 PetscCall(VecGetSize(diag,&n)); 8862 PetscCall(MatGetSize(mat,NULL,&m)); 8863 if (m == n) { 8864 PetscCall(MatDiagonalScale(mat,NULL,diag)); 8865 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8866 } else { 8867 PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag)); 8868 } 8869 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 8870 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8871 PetscFunctionReturn(0); 8872 } 8873 8874 /*@ 8875 MatGetInertia - Gets the inertia from a factored matrix 8876 8877 Collective on Mat 8878 8879 Input Parameter: 8880 . mat - the matrix 8881 8882 Output Parameters: 8883 + nneg - number of negative eigenvalues 8884 . nzero - number of zero eigenvalues 8885 - npos - number of positive eigenvalues 8886 8887 Level: advanced 8888 8889 Notes: 8890 Matrix must have been factored by MatCholeskyFactor() 8891 8892 @*/ 8893 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8894 { 8895 PetscFunctionBegin; 8896 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8897 PetscValidType(mat,1); 8898 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8899 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8900 PetscCheck(mat->ops->getinertia,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8901 PetscCall((*mat->ops->getinertia)(mat,nneg,nzero,npos)); 8902 PetscFunctionReturn(0); 8903 } 8904 8905 /* ----------------------------------------------------------------*/ 8906 /*@C 8907 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8908 8909 Neighbor-wise Collective on Mats 8910 8911 Input Parameters: 8912 + mat - the factored matrix 8913 - b - the right-hand-side vectors 8914 8915 Output Parameter: 8916 . x - the result vectors 8917 8918 Notes: 8919 The vectors b and x cannot be the same. I.e., one cannot 8920 call MatSolves(A,x,x). 8921 8922 Notes: 8923 Most users should employ the simplified KSP interface for linear solvers 8924 instead of working directly with matrix algebra routines such as this. 8925 See, e.g., KSPCreate(). 8926 8927 Level: developer 8928 8929 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`, `MatSolve()` 8930 @*/ 8931 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8932 { 8933 PetscFunctionBegin; 8934 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8935 PetscValidType(mat,1); 8936 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8937 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8938 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8939 8940 PetscCheck(mat->ops->solves,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8941 MatCheckPreallocated(mat,1); 8942 PetscCall(PetscLogEventBegin(MAT_Solves,mat,0,0,0)); 8943 PetscCall((*mat->ops->solves)(mat,b,x)); 8944 PetscCall(PetscLogEventEnd(MAT_Solves,mat,0,0,0)); 8945 PetscFunctionReturn(0); 8946 } 8947 8948 /*@ 8949 MatIsSymmetric - Test whether a matrix is symmetric 8950 8951 Collective on Mat 8952 8953 Input Parameters: 8954 + A - the matrix to test 8955 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8956 8957 Output Parameters: 8958 . flg - the result 8959 8960 Notes: 8961 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8962 8963 If the matrix does not yet know if it is symmetric or not this can be an expensive operation, also available `MatIsSymmetricKnown()` 8964 8965 Level: intermediate 8966 8967 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetricKnown()` 8968 @*/ 8969 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8970 { 8971 PetscFunctionBegin; 8972 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8973 PetscValidBoolPointer(flg,3); 8974 8975 if (A->symmetric == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 8976 else if (A->symmetric == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 8977 else { 8978 if (!A->ops->issymmetric) { 8979 MatType mattype; 8980 PetscCall(MatGetType(A,&mattype)); 8981 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 8982 } 8983 PetscCall((*A->ops->issymmetric)(A,tol,flg)); 8984 if (!tol) PetscCall(MatSetOption(A,MAT_SYMMETRIC,*flg)); 8985 } 8986 PetscFunctionReturn(0); 8987 } 8988 8989 /*@ 8990 MatIsHermitian - Test whether a matrix is Hermitian 8991 8992 Collective on Mat 8993 8994 Input Parameters: 8995 + A - the matrix to test 8996 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8997 8998 Output Parameters: 8999 . flg - the result 9000 9001 Level: intermediate 9002 9003 Notes: 9004 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9005 9006 If the matrix does not yet know if it is hermitian or not this can be an expensive operation, also available `MatIsHermitianKnown()` 9007 9008 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitianKnown()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, 9009 `MatIsSymmetricKnown()`, `MatIsSymmetric()` 9010 @*/ 9011 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 9012 { 9013 PetscFunctionBegin; 9014 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9015 PetscValidBoolPointer(flg,3); 9016 9017 if (A->hermitian == PETSC_BOOL3_TRUE) *flg = PETSC_TRUE; 9018 else if (A->hermitian == PETSC_BOOL3_FALSE) *flg = PETSC_FALSE; 9019 else { 9020 if (!A->ops->ishermitian) { 9021 MatType mattype; 9022 PetscCall(MatGetType(A,&mattype)); 9023 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 9024 } 9025 PetscCall((*A->ops->ishermitian)(A,tol,flg)); 9026 if (!tol) PetscCall(MatSetOption(A,MAT_HERMITIAN,*flg)); 9027 } 9028 PetscFunctionReturn(0); 9029 } 9030 9031 /*@ 9032 MatIsSymmetricKnown - Checks if a matrix knows if it is symmetric or not and its symmetric state 9033 9034 Not Collective 9035 9036 Input Parameter: 9037 . A - the matrix to check 9038 9039 Output Parameters: 9040 + set - PETSC_TRUE if the matrix knows its symmetry state (this tells you if the next flag is valid) 9041 - flg - the result (only valid if set is PETSC_TRUE) 9042 9043 Level: advanced 9044 9045 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 9046 if you want it explicitly checked 9047 9048 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9049 @*/ 9050 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9051 { 9052 PetscFunctionBegin; 9053 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9054 PetscValidBoolPointer(set,2); 9055 PetscValidBoolPointer(flg,3); 9056 if (A->symmetric != PETSC_BOOL3_UNKNOWN) { 9057 *set = PETSC_TRUE; 9058 *flg = PetscBool3ToBool(A->symmetric); 9059 } else { 9060 *set = PETSC_FALSE; 9061 } 9062 PetscFunctionReturn(0); 9063 } 9064 9065 /*@ 9066 MatIsSPDKnown - Checks if a matrix knows if it is symmetric positive definite or not and its symmetric positive definite state 9067 9068 Not Collective 9069 9070 Input Parameter: 9071 . A - the matrix to check 9072 9073 Output Parameters: 9074 + set - PETSC_TRUE if the matrix knows its symmetric positive definite state (this tells you if the next flag is valid) 9075 - flg - the result (only valid if set is PETSC_TRUE) 9076 9077 Level: advanced 9078 9079 Note: 9080 Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). 9081 9082 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9083 @*/ 9084 PetscErrorCode MatIsSPDKnown(Mat A,PetscBool *set,PetscBool *flg) 9085 { 9086 PetscFunctionBegin; 9087 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9088 PetscValidBoolPointer(set,2); 9089 PetscValidBoolPointer(flg,3); 9090 if (A->spd != PETSC_BOOL3_UNKNOWN) { 9091 *set = PETSC_TRUE; 9092 *flg = PetscBool3ToBool(A->spd); 9093 } else { 9094 *set = PETSC_FALSE; 9095 } 9096 PetscFunctionReturn(0); 9097 } 9098 9099 /*@ 9100 MatIsHermitianKnown - Checks if a matrix knows if it is Hermitian or not and its Hermitian state 9101 9102 Not Collective 9103 9104 Input Parameter: 9105 . A - the matrix to check 9106 9107 Output Parameters: 9108 + set - PETSC_TRUE if the matrix knows its Hermitian state (this tells you if the next flag is valid) 9109 - flg - the result (only valid if set is PETSC_TRUE) 9110 9111 Level: advanced 9112 9113 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 9114 if you want it explicitly checked 9115 9116 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()` 9117 @*/ 9118 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 9119 { 9120 PetscFunctionBegin; 9121 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9122 PetscValidBoolPointer(set,2); 9123 PetscValidBoolPointer(flg,3); 9124 if (A->hermitian != PETSC_BOOL3_UNKNOWN) { 9125 *set = PETSC_TRUE; 9126 *flg = PetscBool3ToBool(A->hermitian); 9127 } else { 9128 *set = PETSC_FALSE; 9129 } 9130 PetscFunctionReturn(0); 9131 } 9132 9133 /*@ 9134 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 9135 9136 Collective on Mat 9137 9138 Input Parameter: 9139 . A - the matrix to test 9140 9141 Output Parameters: 9142 . flg - the result 9143 9144 Notes: 9145 If the matrix does yet know it is structurally symmetric this can be an expensive operation, also available `MatIsStructurallySymmetricKnown()` 9146 9147 Level: intermediate 9148 9149 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsSymmetric()`, `MatSetOption()`, `MatIsStructurallySymmetricKnown()` 9150 @*/ 9151 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 9152 { 9153 PetscFunctionBegin; 9154 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9155 PetscValidBoolPointer(flg,2); 9156 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9157 *flg = PetscBool3ToBool(A->structurally_symmetric); 9158 } else { 9159 PetscCheck(A->ops->isstructurallysymmetric,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type %s does not support checking for structural symmetry",((PetscObject)A)->type_name); 9160 PetscCall((*A->ops->isstructurallysymmetric)(A,flg)); 9161 PetscCall(MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg)); 9162 } 9163 PetscFunctionReturn(0); 9164 } 9165 9166 /*@ 9167 MatIsStructurallySymmetricKnown - Checks if a matrix knows if it is structurally symmetric or not and its structurally symmetric state 9168 9169 Not Collective 9170 9171 Input Parameter: 9172 . A - the matrix to check 9173 9174 Output Parameters: 9175 + set - PETSC_TRUE if the matrix knows its structurally symmetric state (this tells you if the next flag is valid) 9176 - flg - the result (only valid if set is PETSC_TRUE) 9177 9178 Level: advanced 9179 9180 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()`, `MatIsHermitianKnown()` 9181 @*/ 9182 PetscErrorCode MatIsStructurallySymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9183 { 9184 PetscFunctionBegin; 9185 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9186 PetscValidBoolPointer(set,2); 9187 PetscValidBoolPointer(flg,3); 9188 if (A->structurally_symmetric != PETSC_BOOL3_UNKNOWN) { 9189 *set = PETSC_TRUE; 9190 *flg = PetscBool3ToBool(A->structurally_symmetric); 9191 } else { 9192 *set = PETSC_FALSE; 9193 } 9194 PetscFunctionReturn(0); 9195 } 9196 9197 /*@ 9198 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 9199 to be communicated to other processors during the MatAssemblyBegin/End() process 9200 9201 Not collective 9202 9203 Input Parameter: 9204 . vec - the vector 9205 9206 Output Parameters: 9207 + nstash - the size of the stash 9208 . reallocs - the number of additional mallocs incurred. 9209 . bnstash - the size of the block stash 9210 - breallocs - the number of additional mallocs incurred.in the block stash 9211 9212 Level: advanced 9213 9214 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashSetInitialSize()` 9215 9216 @*/ 9217 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 9218 { 9219 PetscFunctionBegin; 9220 PetscCall(MatStashGetInfo_Private(&mat->stash,nstash,reallocs)); 9221 PetscCall(MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs)); 9222 PetscFunctionReturn(0); 9223 } 9224 9225 /*@C 9226 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 9227 parallel layout 9228 9229 Collective on Mat 9230 9231 Input Parameter: 9232 . mat - the matrix 9233 9234 Output Parameters: 9235 + right - (optional) vector that the matrix can be multiplied against 9236 - left - (optional) vector that the matrix vector product can be stored in 9237 9238 Notes: 9239 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(). 9240 9241 Notes: 9242 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 9243 9244 Level: advanced 9245 9246 .seealso: `MatCreate()`, `VecDestroy()` 9247 @*/ 9248 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 9249 { 9250 PetscFunctionBegin; 9251 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9252 PetscValidType(mat,1); 9253 if (mat->ops->getvecs) { 9254 PetscCall((*mat->ops->getvecs)(mat,right,left)); 9255 } else { 9256 PetscInt rbs,cbs; 9257 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 9258 if (right) { 9259 PetscCheck(mat->cmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 9260 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),right)); 9261 PetscCall(VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE)); 9262 PetscCall(VecSetBlockSize(*right,cbs)); 9263 PetscCall(VecSetType(*right,mat->defaultvectype)); 9264 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9265 if (mat->boundtocpu && mat->bindingpropagates) { 9266 PetscCall(VecSetBindingPropagates(*right,PETSC_TRUE)); 9267 PetscCall(VecBindToCPU(*right,PETSC_TRUE)); 9268 } 9269 #endif 9270 PetscCall(PetscLayoutReference(mat->cmap,&(*right)->map)); 9271 } 9272 if (left) { 9273 PetscCheck(mat->rmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 9274 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),left)); 9275 PetscCall(VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE)); 9276 PetscCall(VecSetBlockSize(*left,rbs)); 9277 PetscCall(VecSetType(*left,mat->defaultvectype)); 9278 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9279 if (mat->boundtocpu && mat->bindingpropagates) { 9280 PetscCall(VecSetBindingPropagates(*left,PETSC_TRUE)); 9281 PetscCall(VecBindToCPU(*left,PETSC_TRUE)); 9282 } 9283 #endif 9284 PetscCall(PetscLayoutReference(mat->rmap,&(*left)->map)); 9285 } 9286 } 9287 PetscFunctionReturn(0); 9288 } 9289 9290 /*@C 9291 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 9292 with default values. 9293 9294 Not Collective 9295 9296 Input Parameters: 9297 . info - the MatFactorInfo data structure 9298 9299 Notes: 9300 The solvers are generally used through the KSP and PC objects, for example 9301 PCLU, PCILU, PCCHOLESKY, PCICC 9302 9303 Level: developer 9304 9305 .seealso: `MatFactorInfo` 9306 9307 Developer Note: fortran interface is not autogenerated as the f90 9308 interface definition cannot be generated correctly [due to MatFactorInfo] 9309 9310 @*/ 9311 9312 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 9313 { 9314 PetscFunctionBegin; 9315 PetscCall(PetscMemzero(info,sizeof(MatFactorInfo))); 9316 PetscFunctionReturn(0); 9317 } 9318 9319 /*@ 9320 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9321 9322 Collective on Mat 9323 9324 Input Parameters: 9325 + mat - the factored matrix 9326 - is - the index set defining the Schur indices (0-based) 9327 9328 Notes: 9329 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9330 9331 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9332 9333 Level: developer 9334 9335 .seealso: `MatGetFactor()`, `MatFactorGetSchurComplement()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSolveSchurComplement()`, 9336 `MatFactorSolveSchurComplementTranspose()`, `MatFactorSolveSchurComplement()` 9337 9338 @*/ 9339 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 9340 { 9341 PetscErrorCode (*f)(Mat,IS); 9342 9343 PetscFunctionBegin; 9344 PetscValidType(mat,1); 9345 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9346 PetscValidType(is,2); 9347 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9348 PetscCheckSameComm(mat,1,is,2); 9349 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9350 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f)); 9351 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9352 PetscCall(MatDestroy(&mat->schur)); 9353 PetscCall((*f)(mat,is)); 9354 PetscCheck(mat->schur,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9355 PetscFunctionReturn(0); 9356 } 9357 9358 /*@ 9359 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9360 9361 Logically Collective on Mat 9362 9363 Input Parameters: 9364 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9365 . S - location where to return the Schur complement, can be NULL 9366 - status - the status of the Schur complement matrix, can be NULL 9367 9368 Notes: 9369 You must call MatFactorSetSchurIS() before calling this routine. 9370 9371 The routine provides a copy of the Schur matrix stored within the solver data structures. 9372 The caller must destroy the object when it is no longer needed. 9373 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9374 9375 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) 9376 9377 Developer Notes: 9378 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9379 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc 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()`, `MatFactorGetSchurComplement()`, `MatFactorSchurStatus` 9388 @*/ 9389 PetscErrorCode MatFactorCreateSchurComplement(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) { 9396 PetscErrorCode (*f)(Mat,Mat*); 9397 9398 PetscCall(PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f)); 9399 if (f) { 9400 PetscCall((*f)(F,S)); 9401 } else { 9402 PetscCall(MatDuplicate(F->schur,MAT_COPY_VALUES,S)); 9403 } 9404 } 9405 if (status) *status = F->schur_status; 9406 PetscFunctionReturn(0); 9407 } 9408 9409 /*@ 9410 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9411 9412 Logically Collective on Mat 9413 9414 Input Parameters: 9415 + F - the factored matrix obtained by calling MatGetFactor() 9416 . *S - location where to return the Schur complement, can be NULL 9417 - status - the status of the Schur complement matrix, can be NULL 9418 9419 Notes: 9420 You must call MatFactorSetSchurIS() before calling this routine. 9421 9422 Schur complement mode is currently implemented for sequential matrices. 9423 The routine returns a the Schur Complement stored within the data strutures of the solver. 9424 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9425 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9426 9427 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9428 9429 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9430 9431 Level: advanced 9432 9433 References: 9434 9435 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9436 @*/ 9437 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9438 { 9439 PetscFunctionBegin; 9440 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9441 if (S) PetscValidPointer(S,2); 9442 if (status) PetscValidPointer(status,3); 9443 if (S) *S = F->schur; 9444 if (status) *status = F->schur_status; 9445 PetscFunctionReturn(0); 9446 } 9447 9448 /*@ 9449 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9450 9451 Logically Collective on Mat 9452 9453 Input Parameters: 9454 + F - the factored matrix obtained by calling MatGetFactor() 9455 . *S - location where the Schur complement is stored 9456 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9457 9458 Notes: 9459 9460 Level: advanced 9461 9462 References: 9463 9464 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9465 @*/ 9466 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9467 { 9468 PetscFunctionBegin; 9469 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9470 if (S) { 9471 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9472 *S = NULL; 9473 } 9474 F->schur_status = status; 9475 PetscCall(MatFactorUpdateSchurStatus_Private(F)); 9476 PetscFunctionReturn(0); 9477 } 9478 9479 /*@ 9480 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9481 9482 Logically Collective on Mat 9483 9484 Input Parameters: 9485 + F - the factored matrix obtained by calling MatGetFactor() 9486 . rhs - location where the right hand side of the Schur complement system is stored 9487 - sol - location where the solution of the Schur complement system has to be returned 9488 9489 Notes: 9490 The sizes of the vectors should match the size of the Schur complement 9491 9492 Must be called after MatFactorSetSchurIS() 9493 9494 Level: advanced 9495 9496 References: 9497 9498 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplement()` 9499 @*/ 9500 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9501 { 9502 PetscFunctionBegin; 9503 PetscValidType(F,1); 9504 PetscValidType(rhs,2); 9505 PetscValidType(sol,3); 9506 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9507 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9508 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9509 PetscCheckSameComm(F,1,rhs,2); 9510 PetscCheckSameComm(F,1,sol,3); 9511 PetscCall(MatFactorFactorizeSchurComplement(F)); 9512 switch (F->schur_status) { 9513 case MAT_FACTOR_SCHUR_FACTORED: 9514 PetscCall(MatSolveTranspose(F->schur,rhs,sol)); 9515 break; 9516 case MAT_FACTOR_SCHUR_INVERTED: 9517 PetscCall(MatMultTranspose(F->schur,rhs,sol)); 9518 break; 9519 default: 9520 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9521 } 9522 PetscFunctionReturn(0); 9523 } 9524 9525 /*@ 9526 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9527 9528 Logically Collective on Mat 9529 9530 Input Parameters: 9531 + F - the factored matrix obtained by calling MatGetFactor() 9532 . rhs - location where the right hand side of the Schur complement system is stored 9533 - sol - location where the solution of the Schur complement system has to be returned 9534 9535 Notes: 9536 The sizes of the vectors should match the size of the Schur complement 9537 9538 Must be called after MatFactorSetSchurIS() 9539 9540 Level: advanced 9541 9542 References: 9543 9544 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplementTranspose()` 9545 @*/ 9546 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9547 { 9548 PetscFunctionBegin; 9549 PetscValidType(F,1); 9550 PetscValidType(rhs,2); 9551 PetscValidType(sol,3); 9552 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9553 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9554 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9555 PetscCheckSameComm(F,1,rhs,2); 9556 PetscCheckSameComm(F,1,sol,3); 9557 PetscCall(MatFactorFactorizeSchurComplement(F)); 9558 switch (F->schur_status) { 9559 case MAT_FACTOR_SCHUR_FACTORED: 9560 PetscCall(MatSolve(F->schur,rhs,sol)); 9561 break; 9562 case MAT_FACTOR_SCHUR_INVERTED: 9563 PetscCall(MatMult(F->schur,rhs,sol)); 9564 break; 9565 default: 9566 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9567 } 9568 PetscFunctionReturn(0); 9569 } 9570 9571 /*@ 9572 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9573 9574 Logically Collective on Mat 9575 9576 Input Parameters: 9577 . F - the factored matrix obtained by calling MatGetFactor() 9578 9579 Notes: 9580 Must be called after MatFactorSetSchurIS(). 9581 9582 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9583 9584 Level: advanced 9585 9586 References: 9587 9588 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorCreateSchurComplement()` 9589 @*/ 9590 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9591 { 9592 PetscFunctionBegin; 9593 PetscValidType(F,1); 9594 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9595 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9596 PetscCall(MatFactorFactorizeSchurComplement(F)); 9597 PetscCall(MatFactorInvertSchurComplement_Private(F)); 9598 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9599 PetscFunctionReturn(0); 9600 } 9601 9602 /*@ 9603 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9604 9605 Logically Collective on Mat 9606 9607 Input Parameters: 9608 . F - the factored matrix obtained by calling MatGetFactor() 9609 9610 Notes: 9611 Must be called after MatFactorSetSchurIS(). 9612 9613 Level: advanced 9614 9615 References: 9616 9617 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorInvertSchurComplement()` 9618 @*/ 9619 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9620 { 9621 PetscFunctionBegin; 9622 PetscValidType(F,1); 9623 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9624 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9625 PetscCall(MatFactorFactorizeSchurComplement_Private(F)); 9626 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9627 PetscFunctionReturn(0); 9628 } 9629 9630 /*@ 9631 MatPtAP - Creates the matrix product C = P^T * A * P 9632 9633 Neighbor-wise Collective on Mat 9634 9635 Input Parameters: 9636 + A - the matrix 9637 . P - the projection matrix 9638 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9639 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9640 if the result is a dense matrix this is irrelevant 9641 9642 Output Parameters: 9643 . C - the product matrix 9644 9645 Notes: 9646 C will be created and must be destroyed by the user with MatDestroy(). 9647 9648 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9649 9650 Level: intermediate 9651 9652 .seealso: `MatMatMult()`, `MatRARt()` 9653 @*/ 9654 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9655 { 9656 PetscFunctionBegin; 9657 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9658 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9659 9660 if (scall == MAT_INITIAL_MATRIX) { 9661 PetscCall(MatProductCreate(A,P,NULL,C)); 9662 PetscCall(MatProductSetType(*C,MATPRODUCT_PtAP)); 9663 PetscCall(MatProductSetAlgorithm(*C,"default")); 9664 PetscCall(MatProductSetFill(*C,fill)); 9665 9666 (*C)->product->api_user = PETSC_TRUE; 9667 PetscCall(MatProductSetFromOptions(*C)); 9668 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); 9669 PetscCall(MatProductSymbolic(*C)); 9670 } else { /* scall == MAT_REUSE_MATRIX */ 9671 PetscCall(MatProductReplaceMats(A,P,NULL,*C)); 9672 } 9673 9674 PetscCall(MatProductNumeric(*C)); 9675 (*C)->symmetric = A->symmetric; 9676 (*C)->spd = A->spd; 9677 PetscFunctionReturn(0); 9678 } 9679 9680 /*@ 9681 MatRARt - Creates the matrix product C = R * A * R^T 9682 9683 Neighbor-wise Collective on Mat 9684 9685 Input Parameters: 9686 + A - the matrix 9687 . R - the projection matrix 9688 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9689 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9690 if the result is a dense matrix this is irrelevant 9691 9692 Output Parameters: 9693 . C - the product matrix 9694 9695 Notes: 9696 C will be created and must be destroyed by the user with MatDestroy(). 9697 9698 This routine is currently only implemented for pairs of AIJ matrices and classes 9699 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9700 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9701 We recommend using MatPtAP(). 9702 9703 Level: intermediate 9704 9705 .seealso: `MatMatMult()`, `MatPtAP()` 9706 @*/ 9707 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9708 { 9709 PetscFunctionBegin; 9710 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9711 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9712 9713 if (scall == MAT_INITIAL_MATRIX) { 9714 PetscCall(MatProductCreate(A,R,NULL,C)); 9715 PetscCall(MatProductSetType(*C,MATPRODUCT_RARt)); 9716 PetscCall(MatProductSetAlgorithm(*C,"default")); 9717 PetscCall(MatProductSetFill(*C,fill)); 9718 9719 (*C)->product->api_user = PETSC_TRUE; 9720 PetscCall(MatProductSetFromOptions(*C)); 9721 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); 9722 PetscCall(MatProductSymbolic(*C)); 9723 } else { /* scall == MAT_REUSE_MATRIX */ 9724 PetscCall(MatProductReplaceMats(A,R,NULL,*C)); 9725 } 9726 9727 PetscCall(MatProductNumeric(*C)); 9728 if (A->symmetric == PETSC_BOOL3_TRUE) { 9729 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9730 } 9731 PetscFunctionReturn(0); 9732 } 9733 9734 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C) 9735 { 9736 PetscFunctionBegin; 9737 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9738 9739 if (scall == MAT_INITIAL_MATRIX) { 9740 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype])); 9741 PetscCall(MatProductCreate(A,B,NULL,C)); 9742 PetscCall(MatProductSetType(*C,ptype)); 9743 PetscCall(MatProductSetAlgorithm(*C,MATPRODUCTALGORITHMDEFAULT)); 9744 PetscCall(MatProductSetFill(*C,fill)); 9745 9746 (*C)->product->api_user = PETSC_TRUE; 9747 PetscCall(MatProductSetFromOptions(*C)); 9748 PetscCall(MatProductSymbolic(*C)); 9749 } else { /* scall == MAT_REUSE_MATRIX */ 9750 Mat_Product *product = (*C)->product; 9751 PetscBool isdense; 9752 9753 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"")); 9754 if (isdense && product && product->type != ptype) { 9755 PetscCall(MatProductClear(*C)); 9756 product = NULL; 9757 } 9758 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n",product ? "with" : "without",MatProductTypes[ptype])); 9759 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9760 if (isdense) { 9761 PetscCall(MatProductCreate_Private(A,B,NULL,*C)); 9762 product = (*C)->product; 9763 product->fill = fill; 9764 product->api_user = PETSC_TRUE; 9765 product->clear = PETSC_TRUE; 9766 9767 PetscCall(MatProductSetType(*C,ptype)); 9768 PetscCall(MatProductSetFromOptions(*C)); 9769 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); 9770 PetscCall(MatProductSymbolic(*C)); 9771 } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first"); 9772 } else { /* user may change input matrices A or B when REUSE */ 9773 PetscCall(MatProductReplaceMats(A,B,NULL,*C)); 9774 } 9775 } 9776 PetscCall(MatProductNumeric(*C)); 9777 PetscFunctionReturn(0); 9778 } 9779 9780 /*@ 9781 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9782 9783 Neighbor-wise Collective on Mat 9784 9785 Input Parameters: 9786 + A - the left matrix 9787 . B - the right matrix 9788 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9789 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9790 if the result is a dense matrix this is irrelevant 9791 9792 Output Parameters: 9793 . C - the product matrix 9794 9795 Notes: 9796 Unless scall is MAT_REUSE_MATRIX C will be created. 9797 9798 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 9799 call to this function with MAT_INITIAL_MATRIX. 9800 9801 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9802 9803 If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic()/MatProductReplaceMats(), and call MatProductNumeric() repeatedly. 9804 9805 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. 9806 9807 Example of Usage: 9808 .vb 9809 MatProductCreate(A,B,NULL,&C); 9810 MatProductSetType(C,MATPRODUCT_AB); 9811 MatProductSymbolic(C); 9812 MatProductNumeric(C); // compute C=A * B 9813 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9814 MatProductNumeric(C); 9815 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9816 MatProductNumeric(C); 9817 .ve 9818 9819 Level: intermediate 9820 9821 .seealso: `MatTransposeMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`, `MatProductCreate()`, `MatProductSymbolic()`, `MatProductReplaceMats()`, `MatProductNumeric()` 9822 @*/ 9823 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9824 { 9825 PetscFunctionBegin; 9826 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C)); 9827 PetscFunctionReturn(0); 9828 } 9829 9830 /*@ 9831 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9832 9833 Neighbor-wise Collective on Mat 9834 9835 Input Parameters: 9836 + A - the left matrix 9837 . B - the right matrix 9838 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9839 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9840 9841 Output Parameters: 9842 . C - the product matrix 9843 9844 Notes: 9845 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9846 9847 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9848 9849 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9850 actually needed. 9851 9852 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9853 and for pairs of MPIDense matrices. 9854 9855 Options Database Keys: 9856 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorithms for MPIDense matrices: the 9857 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9858 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9859 9860 Level: intermediate 9861 9862 .seealso: `MatMatMult()`, `MatTransposeMatMult()` `MatPtAP()` 9863 @*/ 9864 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9865 { 9866 PetscFunctionBegin; 9867 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C)); 9868 if (A == B) { 9869 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9870 } 9871 PetscFunctionReturn(0); 9872 } 9873 9874 /*@ 9875 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9876 9877 Neighbor-wise Collective on Mat 9878 9879 Input Parameters: 9880 + A - the left matrix 9881 . B - the right matrix 9882 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9883 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9884 9885 Output Parameters: 9886 . C - the product matrix 9887 9888 Notes: 9889 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9890 9891 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 9892 9893 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9894 actually needed. 9895 9896 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9897 which inherit from SeqAIJ. C will be of the same type as the input matrices. 9898 9899 Level: intermediate 9900 9901 .seealso: `MatMatMult()`, `MatMatTransposeMult()`, `MatPtAP()` 9902 @*/ 9903 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9904 { 9905 PetscFunctionBegin; 9906 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C)); 9907 PetscFunctionReturn(0); 9908 } 9909 9910 /*@ 9911 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9912 9913 Neighbor-wise Collective on Mat 9914 9915 Input Parameters: 9916 + A - the left matrix 9917 . B - the middle matrix 9918 . C - the right matrix 9919 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9920 - 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 9921 if the result is a dense matrix this is irrelevant 9922 9923 Output Parameters: 9924 . D - the product matrix 9925 9926 Notes: 9927 Unless scall is MAT_REUSE_MATRIX D will be created. 9928 9929 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9930 9931 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9932 actually needed. 9933 9934 If you have many matrices with the same non-zero structure to multiply, you 9935 should use MAT_REUSE_MATRIX in all calls but the first 9936 9937 Level: intermediate 9938 9939 .seealso: `MatMatMult`, `MatPtAP()`, `MatMatTransposeMult()`, `MatTransposeMatMult()` 9940 @*/ 9941 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9942 { 9943 PetscFunctionBegin; 9944 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6); 9945 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9946 9947 if (scall == MAT_INITIAL_MATRIX) { 9948 PetscCall(MatProductCreate(A,B,C,D)); 9949 PetscCall(MatProductSetType(*D,MATPRODUCT_ABC)); 9950 PetscCall(MatProductSetAlgorithm(*D,"default")); 9951 PetscCall(MatProductSetFill(*D,fill)); 9952 9953 (*D)->product->api_user = PETSC_TRUE; 9954 PetscCall(MatProductSetFromOptions(*D)); 9955 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); 9956 PetscCall(MatProductSymbolic(*D)); 9957 } else { /* user may change input matrices when REUSE */ 9958 PetscCall(MatProductReplaceMats(A,B,C,*D)); 9959 } 9960 PetscCall(MatProductNumeric(*D)); 9961 PetscFunctionReturn(0); 9962 } 9963 9964 /*@ 9965 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9966 9967 Collective on Mat 9968 9969 Input Parameters: 9970 + mat - the matrix 9971 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9972 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 9973 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9974 9975 Output Parameter: 9976 . matredundant - redundant matrix 9977 9978 Notes: 9979 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9980 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9981 9982 This routine creates the duplicated matrices in the subcommunicators; you should NOT create them before 9983 calling it. 9984 9985 Level: advanced 9986 9987 .seealso: `MatDestroy()` 9988 @*/ 9989 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 9990 { 9991 MPI_Comm comm; 9992 PetscMPIInt size; 9993 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 9994 Mat_Redundant *redund=NULL; 9995 PetscSubcomm psubcomm=NULL; 9996 MPI_Comm subcomm_in=subcomm; 9997 Mat *matseq; 9998 IS isrow,iscol; 9999 PetscBool newsubcomm=PETSC_FALSE; 10000 10001 PetscFunctionBegin; 10002 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10003 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10004 PetscValidPointer(*matredundant,5); 10005 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10006 } 10007 10008 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10009 if (size == 1 || nsubcomm == 1) { 10010 if (reuse == MAT_INITIAL_MATRIX) { 10011 PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,matredundant)); 10012 } else { 10013 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"); 10014 PetscCall(MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN)); 10015 } 10016 PetscFunctionReturn(0); 10017 } 10018 10019 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10020 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10021 MatCheckPreallocated(mat,1); 10022 10023 PetscCall(PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0)); 10024 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10025 /* create psubcomm, then get subcomm */ 10026 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10027 PetscCallMPI(MPI_Comm_size(comm,&size)); 10028 PetscCheck(nsubcomm >= 1 && nsubcomm <= size,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %d",size); 10029 10030 PetscCall(PetscSubcommCreate(comm,&psubcomm)); 10031 PetscCall(PetscSubcommSetNumber(psubcomm,nsubcomm)); 10032 PetscCall(PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS)); 10033 PetscCall(PetscSubcommSetFromOptions(psubcomm)); 10034 PetscCall(PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL)); 10035 newsubcomm = PETSC_TRUE; 10036 PetscCall(PetscSubcommDestroy(&psubcomm)); 10037 } 10038 10039 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10040 if (reuse == MAT_INITIAL_MATRIX) { 10041 mloc_sub = PETSC_DECIDE; 10042 nloc_sub = PETSC_DECIDE; 10043 if (bs < 1) { 10044 PetscCall(PetscSplitOwnership(subcomm,&mloc_sub,&M)); 10045 PetscCall(PetscSplitOwnership(subcomm,&nloc_sub,&N)); 10046 } else { 10047 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M)); 10048 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N)); 10049 } 10050 PetscCallMPI(MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm)); 10051 rstart = rend - mloc_sub; 10052 PetscCall(ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow)); 10053 PetscCall(ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol)); 10054 } else { /* reuse == MAT_REUSE_MATRIX */ 10055 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"); 10056 /* retrieve subcomm */ 10057 PetscCall(PetscObjectGetComm((PetscObject)(*matredundant),&subcomm)); 10058 redund = (*matredundant)->redundant; 10059 isrow = redund->isrow; 10060 iscol = redund->iscol; 10061 matseq = redund->matseq; 10062 } 10063 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq)); 10064 10065 /* get matredundant over subcomm */ 10066 if (reuse == MAT_INITIAL_MATRIX) { 10067 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant)); 10068 10069 /* create a supporting struct and attach it to C for reuse */ 10070 PetscCall(PetscNewLog(*matredundant,&redund)); 10071 (*matredundant)->redundant = redund; 10072 redund->isrow = isrow; 10073 redund->iscol = iscol; 10074 redund->matseq = matseq; 10075 if (newsubcomm) { 10076 redund->subcomm = subcomm; 10077 } else { 10078 redund->subcomm = MPI_COMM_NULL; 10079 } 10080 } else { 10081 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant)); 10082 } 10083 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 10084 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 10085 PetscCall(MatBindToCPU(*matredundant,PETSC_TRUE)); 10086 PetscCall(MatSetBindingPropagates(*matredundant,PETSC_TRUE)); 10087 } 10088 #endif 10089 PetscCall(PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0)); 10090 PetscFunctionReturn(0); 10091 } 10092 10093 /*@C 10094 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10095 a given 'mat' object. Each submatrix can span multiple procs. 10096 10097 Collective on Mat 10098 10099 Input Parameters: 10100 + mat - the matrix 10101 . subcomm - the subcommunicator obtained by com_split(comm) 10102 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10103 10104 Output Parameter: 10105 . subMat - 'parallel submatrices each spans a given subcomm 10106 10107 Notes: 10108 The submatrix partition across processors is dictated by 'subComm' a 10109 communicator obtained by MPI_comm_split(). The subComm 10110 is not restriced to be grouped with consecutive original ranks. 10111 10112 Due the MPI_Comm_split() usage, the parallel layout of the submatrices 10113 map directly to the layout of the original matrix [wrt the local 10114 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10115 into the 'DiagonalMat' of the subMat, hence it is used directly from 10116 the subMat. However the offDiagMat looses some columns - and this is 10117 reconstructed with MatSetValues() 10118 10119 Level: advanced 10120 10121 .seealso: `MatCreateSubMatrices()` 10122 @*/ 10123 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10124 { 10125 PetscMPIInt commsize,subCommSize; 10126 10127 PetscFunctionBegin; 10128 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize)); 10129 PetscCallMPI(MPI_Comm_size(subComm,&subCommSize)); 10130 PetscCheck(subCommSize <= commsize,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %d < SubCommZize %d",commsize,subCommSize); 10131 10132 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"); 10133 PetscCall(PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0)); 10134 PetscCall((*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat)); 10135 PetscCall(PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0)); 10136 PetscFunctionReturn(0); 10137 } 10138 10139 /*@ 10140 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10141 10142 Not Collective 10143 10144 Input Parameters: 10145 + mat - matrix to extract local submatrix from 10146 . isrow - local row indices for submatrix 10147 - iscol - local column indices for submatrix 10148 10149 Output Parameter: 10150 . submat - the submatrix 10151 10152 Level: intermediate 10153 10154 Notes: 10155 The submat should be returned with MatRestoreLocalSubMatrix(). 10156 10157 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10158 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10159 10160 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10161 MatSetValuesBlockedLocal() will also be implemented. 10162 10163 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10164 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10165 10166 .seealso: `MatRestoreLocalSubMatrix()`, `MatCreateLocalRef()`, `MatSetLocalToGlobalMapping()` 10167 @*/ 10168 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10169 { 10170 PetscFunctionBegin; 10171 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10172 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10173 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10174 PetscCheckSameComm(isrow,2,iscol,3); 10175 PetscValidPointer(submat,4); 10176 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10177 10178 if (mat->ops->getlocalsubmatrix) { 10179 PetscCall((*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat)); 10180 } else { 10181 PetscCall(MatCreateLocalRef(mat,isrow,iscol,submat)); 10182 } 10183 PetscFunctionReturn(0); 10184 } 10185 10186 /*@ 10187 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10188 10189 Not Collective 10190 10191 Input Parameters: 10192 + mat - matrix to extract local submatrix from 10193 . isrow - local row indices for submatrix 10194 . iscol - local column indices for submatrix 10195 - submat - the submatrix 10196 10197 Level: intermediate 10198 10199 .seealso: `MatGetLocalSubMatrix()` 10200 @*/ 10201 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10202 { 10203 PetscFunctionBegin; 10204 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10205 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10206 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10207 PetscCheckSameComm(isrow,2,iscol,3); 10208 PetscValidPointer(submat,4); 10209 if (*submat) { 10210 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10211 } 10212 10213 if (mat->ops->restorelocalsubmatrix) { 10214 PetscCall((*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat)); 10215 } else { 10216 PetscCall(MatDestroy(submat)); 10217 } 10218 *submat = NULL; 10219 PetscFunctionReturn(0); 10220 } 10221 10222 /* --------------------------------------------------------*/ 10223 /*@ 10224 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10225 10226 Collective on Mat 10227 10228 Input Parameter: 10229 . mat - the matrix 10230 10231 Output Parameter: 10232 . is - if any rows have zero diagonals this contains the list of them 10233 10234 Level: developer 10235 10236 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10237 @*/ 10238 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10239 { 10240 PetscFunctionBegin; 10241 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10242 PetscValidType(mat,1); 10243 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10244 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10245 10246 if (!mat->ops->findzerodiagonals) { 10247 Vec diag; 10248 const PetscScalar *a; 10249 PetscInt *rows; 10250 PetscInt rStart, rEnd, r, nrow = 0; 10251 10252 PetscCall(MatCreateVecs(mat, &diag, NULL)); 10253 PetscCall(MatGetDiagonal(mat, diag)); 10254 PetscCall(MatGetOwnershipRange(mat, &rStart, &rEnd)); 10255 PetscCall(VecGetArrayRead(diag, &a)); 10256 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10257 PetscCall(PetscMalloc1(nrow, &rows)); 10258 nrow = 0; 10259 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10260 PetscCall(VecRestoreArrayRead(diag, &a)); 10261 PetscCall(VecDestroy(&diag)); 10262 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is)); 10263 } else { 10264 PetscCall((*mat->ops->findzerodiagonals)(mat, is)); 10265 } 10266 PetscFunctionReturn(0); 10267 } 10268 10269 /*@ 10270 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10271 10272 Collective on Mat 10273 10274 Input Parameter: 10275 . mat - the matrix 10276 10277 Output Parameter: 10278 . is - contains the list of rows with off block diagonal entries 10279 10280 Level: developer 10281 10282 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10283 @*/ 10284 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10285 { 10286 PetscFunctionBegin; 10287 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10288 PetscValidType(mat,1); 10289 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10290 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10291 10292 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); 10293 PetscCall((*mat->ops->findoffblockdiagonalentries)(mat,is)); 10294 PetscFunctionReturn(0); 10295 } 10296 10297 /*@C 10298 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10299 10300 Collective on Mat 10301 10302 Input Parameters: 10303 . mat - the matrix 10304 10305 Output Parameters: 10306 . values - the block inverses in column major order (FORTRAN-like) 10307 10308 Note: 10309 The size of the blocks is determined by the block size of the matrix. 10310 10311 Fortran Note: 10312 This routine is not available from Fortran. 10313 10314 Level: advanced 10315 10316 .seealso: `MatInvertVariableBlockEnvelope()`, `MatInvertBlockDiagonalMat()` 10317 @*/ 10318 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10319 { 10320 PetscFunctionBegin; 10321 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10322 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10323 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10324 PetscCheck(mat->ops->invertblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10325 PetscCall((*mat->ops->invertblockdiagonal)(mat,values)); 10326 PetscFunctionReturn(0); 10327 } 10328 10329 /*@C 10330 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 10331 10332 Collective on Mat 10333 10334 Input Parameters: 10335 + mat - the matrix 10336 . nblocks - the number of blocks on the process, set with MatSetVariableBlockSizes() 10337 - bsizes - the size of each block on the process, set with MatSetVariableBlockSizes() 10338 10339 Output Parameters: 10340 . values - the block inverses in column major order (FORTRAN-like) 10341 10342 Note: 10343 This routine is not available from Fortran. 10344 10345 Level: advanced 10346 10347 .seealso: `MatInvertBlockDiagonal()`, `MatSetVariableBlockSizes()`, `MatInvertVariableBlockEnvelope()` 10348 @*/ 10349 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10350 { 10351 PetscFunctionBegin; 10352 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10353 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10354 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10355 PetscCheck(mat->ops->invertvariableblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10356 PetscCall((*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values)); 10357 PetscFunctionReturn(0); 10358 } 10359 10360 /*@ 10361 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10362 10363 Collective on Mat 10364 10365 Input Parameters: 10366 . A - the matrix 10367 10368 Output Parameters: 10369 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10370 10371 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10372 10373 Level: advanced 10374 10375 .seealso: `MatInvertBlockDiagonal()` 10376 @*/ 10377 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10378 { 10379 const PetscScalar *vals; 10380 PetscInt *dnnz; 10381 PetscInt m,rstart,rend,bs,i,j; 10382 10383 PetscFunctionBegin; 10384 PetscCall(MatInvertBlockDiagonal(A,&vals)); 10385 PetscCall(MatGetBlockSize(A,&bs)); 10386 PetscCall(MatGetLocalSize(A,&m,NULL)); 10387 PetscCall(MatSetLayouts(C,A->rmap,A->cmap)); 10388 PetscCall(PetscMalloc1(m/bs,&dnnz)); 10389 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10390 PetscCall(MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL)); 10391 PetscCall(PetscFree(dnnz)); 10392 PetscCall(MatGetOwnershipRange(C,&rstart,&rend)); 10393 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE)); 10394 for (i = rstart/bs; i < rend/bs; i++) { 10395 PetscCall(MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES)); 10396 } 10397 PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY)); 10398 PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY)); 10399 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE)); 10400 PetscFunctionReturn(0); 10401 } 10402 10403 /*@C 10404 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10405 via MatTransposeColoringCreate(). 10406 10407 Collective on MatTransposeColoring 10408 10409 Input Parameter: 10410 . c - coloring context 10411 10412 Level: intermediate 10413 10414 .seealso: `MatTransposeColoringCreate()` 10415 @*/ 10416 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10417 { 10418 MatTransposeColoring matcolor=*c; 10419 10420 PetscFunctionBegin; 10421 if (!matcolor) PetscFunctionReturn(0); 10422 if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);} 10423 10424 PetscCall(PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow)); 10425 PetscCall(PetscFree(matcolor->rows)); 10426 PetscCall(PetscFree(matcolor->den2sp)); 10427 PetscCall(PetscFree(matcolor->colorforcol)); 10428 PetscCall(PetscFree(matcolor->columns)); 10429 if (matcolor->brows>0) PetscCall(PetscFree(matcolor->lstart)); 10430 PetscCall(PetscHeaderDestroy(c)); 10431 PetscFunctionReturn(0); 10432 } 10433 10434 /*@C 10435 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10436 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10437 MatTransposeColoring to sparse B. 10438 10439 Collective on MatTransposeColoring 10440 10441 Input Parameters: 10442 + B - sparse matrix B 10443 . Btdense - symbolic dense matrix B^T 10444 - coloring - coloring context created with MatTransposeColoringCreate() 10445 10446 Output Parameter: 10447 . Btdense - dense matrix B^T 10448 10449 Level: advanced 10450 10451 Notes: 10452 These are used internally for some implementations of MatRARt() 10453 10454 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplyDenToSp()` 10455 10456 @*/ 10457 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10458 { 10459 PetscFunctionBegin; 10460 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10461 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,3); 10462 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10463 10464 PetscCheck(B->ops->transcoloringapplysptoden,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10465 PetscCall((B->ops->transcoloringapplysptoden)(coloring,B,Btdense)); 10466 PetscFunctionReturn(0); 10467 } 10468 10469 /*@C 10470 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10471 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10472 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10473 Csp from Cden. 10474 10475 Collective on MatTransposeColoring 10476 10477 Input Parameters: 10478 + coloring - coloring context created with MatTransposeColoringCreate() 10479 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10480 10481 Output Parameter: 10482 . Csp - sparse matrix 10483 10484 Level: advanced 10485 10486 Notes: 10487 These are used internally for some implementations of MatRARt() 10488 10489 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()` 10490 10491 @*/ 10492 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10493 { 10494 PetscFunctionBegin; 10495 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10496 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10497 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10498 10499 PetscCheck(Csp->ops->transcoloringapplydentosp,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10500 PetscCall((Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp)); 10501 PetscCall(MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY)); 10502 PetscCall(MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY)); 10503 PetscFunctionReturn(0); 10504 } 10505 10506 /*@C 10507 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10508 10509 Collective on Mat 10510 10511 Input Parameters: 10512 + mat - the matrix product C 10513 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10514 10515 Output Parameter: 10516 . color - the new coloring context 10517 10518 Level: intermediate 10519 10520 .seealso: `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`, 10521 `MatTransColoringApplyDenToSp()` 10522 @*/ 10523 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10524 { 10525 MatTransposeColoring c; 10526 MPI_Comm comm; 10527 10528 PetscFunctionBegin; 10529 PetscCall(PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0)); 10530 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10531 PetscCall(PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL)); 10532 10533 c->ctype = iscoloring->ctype; 10534 if (mat->ops->transposecoloringcreate) { 10535 PetscCall((*mat->ops->transposecoloringcreate)(mat,iscoloring,c)); 10536 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 10537 10538 *color = c; 10539 PetscCall(PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0)); 10540 PetscFunctionReturn(0); 10541 } 10542 10543 /*@ 10544 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10545 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10546 same, otherwise it will be larger 10547 10548 Not Collective 10549 10550 Input Parameter: 10551 . A - the matrix 10552 10553 Output Parameter: 10554 . state - the current state 10555 10556 Notes: 10557 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10558 different matrices 10559 10560 Level: intermediate 10561 10562 .seealso: `PetscObjectStateGet()` 10563 @*/ 10564 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10565 { 10566 PetscFunctionBegin; 10567 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10568 *state = mat->nonzerostate; 10569 PetscFunctionReturn(0); 10570 } 10571 10572 /*@ 10573 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10574 matrices from each processor 10575 10576 Collective 10577 10578 Input Parameters: 10579 + comm - the communicators the parallel matrix will live on 10580 . seqmat - the input sequential matrices 10581 . n - number of local columns (or PETSC_DECIDE) 10582 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10583 10584 Output Parameter: 10585 . mpimat - the parallel matrix generated 10586 10587 Level: advanced 10588 10589 Notes: 10590 The number of columns of the matrix in EACH processor MUST be the same. 10591 10592 @*/ 10593 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10594 { 10595 PetscMPIInt size; 10596 10597 PetscFunctionBegin; 10598 PetscCallMPI(MPI_Comm_size(comm,&size)); 10599 if (size == 1) { 10600 if (reuse == MAT_INITIAL_MATRIX) { 10601 PetscCall(MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat)); 10602 } else { 10603 PetscCall(MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN)); 10604 } 10605 PetscFunctionReturn(0); 10606 } 10607 10608 PetscCheck(seqmat->ops->creatempimatconcatenateseqmat,PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10609 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"); 10610 10611 PetscCall(PetscLogEventBegin(MAT_Merge,seqmat,0,0,0)); 10612 PetscCall((*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat)); 10613 PetscCall(PetscLogEventEnd(MAT_Merge,seqmat,0,0,0)); 10614 PetscFunctionReturn(0); 10615 } 10616 10617 /*@ 10618 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10619 ranks' ownership ranges. 10620 10621 Collective on A 10622 10623 Input Parameters: 10624 + A - the matrix to create subdomains from 10625 - N - requested number of subdomains 10626 10627 Output Parameters: 10628 + n - number of subdomains resulting on this rank 10629 - iss - IS list with indices of subdomains on this rank 10630 10631 Level: advanced 10632 10633 Notes: 10634 number of subdomains must be smaller than the communicator size 10635 @*/ 10636 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10637 { 10638 MPI_Comm comm,subcomm; 10639 PetscMPIInt size,rank,color; 10640 PetscInt rstart,rend,k; 10641 10642 PetscFunctionBegin; 10643 PetscCall(PetscObjectGetComm((PetscObject)A,&comm)); 10644 PetscCallMPI(MPI_Comm_size(comm,&size)); 10645 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 10646 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); 10647 *n = 1; 10648 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10649 color = rank/k; 10650 PetscCallMPI(MPI_Comm_split(comm,color,rank,&subcomm)); 10651 PetscCall(PetscMalloc1(1,iss)); 10652 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 10653 PetscCall(ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0])); 10654 PetscCallMPI(MPI_Comm_free(&subcomm)); 10655 PetscFunctionReturn(0); 10656 } 10657 10658 /*@ 10659 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10660 10661 If the interpolation and restriction operators are the same, uses MatPtAP. 10662 If they are not the same, use MatMatMatMult. 10663 10664 Once the coarse grid problem is constructed, correct for interpolation operators 10665 that are not of full rank, which can legitimately happen in the case of non-nested 10666 geometric multigrid. 10667 10668 Input Parameters: 10669 + restrct - restriction operator 10670 . dA - fine grid matrix 10671 . interpolate - interpolation operator 10672 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10673 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10674 10675 Output Parameters: 10676 . A - the Galerkin coarse matrix 10677 10678 Options Database Key: 10679 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10680 10681 Level: developer 10682 10683 .seealso: `MatPtAP()`, `MatMatMatMult()` 10684 @*/ 10685 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10686 { 10687 IS zerorows; 10688 Vec diag; 10689 10690 PetscFunctionBegin; 10691 PetscCheck(reuse != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10692 /* Construct the coarse grid matrix */ 10693 if (interpolate == restrct) { 10694 PetscCall(MatPtAP(dA,interpolate,reuse,fill,A)); 10695 } else { 10696 PetscCall(MatMatMatMult(restrct,dA,interpolate,reuse,fill,A)); 10697 } 10698 10699 /* If the interpolation matrix is not of full rank, A will have zero rows. 10700 This can legitimately happen in the case of non-nested geometric multigrid. 10701 In that event, we set the rows of the matrix to the rows of the identity, 10702 ignoring the equations (as the RHS will also be zero). */ 10703 10704 PetscCall(MatFindZeroRows(*A, &zerorows)); 10705 10706 if (zerorows != NULL) { /* if there are any zero rows */ 10707 PetscCall(MatCreateVecs(*A, &diag, NULL)); 10708 PetscCall(MatGetDiagonal(*A, diag)); 10709 PetscCall(VecISSet(diag, zerorows, 1.0)); 10710 PetscCall(MatDiagonalSet(*A, diag, INSERT_VALUES)); 10711 PetscCall(VecDestroy(&diag)); 10712 PetscCall(ISDestroy(&zerorows)); 10713 } 10714 PetscFunctionReturn(0); 10715 } 10716 10717 /*@C 10718 MatSetOperation - Allows user to set a matrix operation for any matrix type 10719 10720 Logically Collective on Mat 10721 10722 Input Parameters: 10723 + mat - the matrix 10724 . op - the name of the operation 10725 - f - the function that provides the operation 10726 10727 Level: developer 10728 10729 Usage: 10730 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10731 $ PetscCall(MatCreateXXX(comm,...&A); 10732 $ PetscCall(MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10733 10734 Notes: 10735 See the file include/petscmat.h for a complete list of matrix 10736 operations, which all have the form MATOP_<OPERATION>, where 10737 <OPERATION> is the name (in all capital letters) of the 10738 user interface routine (e.g., MatMult() -> MATOP_MULT). 10739 10740 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10741 sequence as the usual matrix interface routines, since they 10742 are intended to be accessed via the usual matrix interface 10743 routines, e.g., 10744 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10745 10746 In particular each function MUST return an error code of 0 on success and 10747 nonzero on failure. 10748 10749 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10750 10751 .seealso: `MatGetOperation()`, `MatCreateShell()`, `MatShellSetContext()`, `MatShellSetOperation()` 10752 @*/ 10753 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10754 { 10755 PetscFunctionBegin; 10756 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10757 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10758 mat->ops->viewnative = mat->ops->view; 10759 } 10760 (((void(**)(void))mat->ops)[op]) = f; 10761 PetscFunctionReturn(0); 10762 } 10763 10764 /*@C 10765 MatGetOperation - Gets a matrix operation for any matrix type. 10766 10767 Not Collective 10768 10769 Input Parameters: 10770 + mat - the matrix 10771 - op - the name of the operation 10772 10773 Output Parameter: 10774 . f - the function that provides the operation 10775 10776 Level: developer 10777 10778 Usage: 10779 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10780 $ MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10781 10782 Notes: 10783 See the file include/petscmat.h for a complete list of matrix 10784 operations, which all have the form MATOP_<OPERATION>, where 10785 <OPERATION> is the name (in all capital letters) of the 10786 user interface routine (e.g., MatMult() -> MATOP_MULT). 10787 10788 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10789 10790 .seealso: `MatSetOperation()`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()` 10791 @*/ 10792 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10793 { 10794 PetscFunctionBegin; 10795 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10796 *f = (((void (**)(void))mat->ops)[op]); 10797 PetscFunctionReturn(0); 10798 } 10799 10800 /*@ 10801 MatHasOperation - Determines whether the given matrix supports the particular 10802 operation. 10803 10804 Not Collective 10805 10806 Input Parameters: 10807 + mat - the matrix 10808 - op - the operation, for example, MATOP_GET_DIAGONAL 10809 10810 Output Parameter: 10811 . has - either PETSC_TRUE or PETSC_FALSE 10812 10813 Level: advanced 10814 10815 Notes: 10816 See the file include/petscmat.h for a complete list of matrix 10817 operations, which all have the form MATOP_<OPERATION>, where 10818 <OPERATION> is the name (in all capital letters) of the 10819 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10820 10821 .seealso: `MatCreateShell()` 10822 @*/ 10823 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10824 { 10825 PetscFunctionBegin; 10826 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10827 PetscValidBoolPointer(has,3); 10828 if (mat->ops->hasoperation) { 10829 PetscCall((*mat->ops->hasoperation)(mat,op,has)); 10830 } else { 10831 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10832 else { 10833 *has = PETSC_FALSE; 10834 if (op == MATOP_CREATE_SUBMATRIX) { 10835 PetscMPIInt size; 10836 10837 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10838 if (size == 1) { 10839 PetscCall(MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has)); 10840 } 10841 } 10842 } 10843 } 10844 PetscFunctionReturn(0); 10845 } 10846 10847 /*@ 10848 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10849 of the matrix are congruent 10850 10851 Collective on mat 10852 10853 Input Parameters: 10854 . mat - the matrix 10855 10856 Output Parameter: 10857 . cong - either PETSC_TRUE or PETSC_FALSE 10858 10859 Level: beginner 10860 10861 Notes: 10862 10863 .seealso: `MatCreate()`, `MatSetSizes()` 10864 @*/ 10865 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 10866 { 10867 PetscFunctionBegin; 10868 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10869 PetscValidType(mat,1); 10870 PetscValidBoolPointer(cong,2); 10871 if (!mat->rmap || !mat->cmap) { 10872 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10873 PetscFunctionReturn(0); 10874 } 10875 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10876 PetscCall(PetscLayoutSetUp(mat->rmap)); 10877 PetscCall(PetscLayoutSetUp(mat->cmap)); 10878 PetscCall(PetscLayoutCompare(mat->rmap,mat->cmap,cong)); 10879 if (*cong) mat->congruentlayouts = 1; 10880 else mat->congruentlayouts = 0; 10881 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10882 PetscFunctionReturn(0); 10883 } 10884 10885 PetscErrorCode MatSetInf(Mat A) 10886 { 10887 PetscFunctionBegin; 10888 PetscCheck(A->ops->setinf,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 10889 PetscCall((*A->ops->setinf)(A)); 10890 PetscFunctionReturn(0); 10891 } 10892 10893 /*C 10894 MatCreateGraph - create a scalar matrix, for use in graph algorithms 10895 10896 Collective on mat 10897 10898 Input Parameters: 10899 + A - the matrix 10900 - sym - PETSC_TRUE indicates that the graph will be symmetrized 10901 . scale - PETSC_TRUE indicates that the graph will be scaled with the diagonal 10902 10903 Output Parameter: 10904 . graph - the resulting graph 10905 10906 Level: advanced 10907 10908 Notes: 10909 10910 .seealso: `MatCreate()`, `MatFilter()` 10911 */ 10912 PETSC_EXTERN PetscErrorCode MatCreateGraph(Mat A, PetscBool sym, PetscBool scale, Mat *graph) 10913 { 10914 PetscFunctionBegin; 10915 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10916 PetscValidType(A,1); 10917 PetscValidPointer(graph,3); 10918 PetscCheck(A->ops->creategraph,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 10919 PetscCall((*A->ops->creategraph)(A,sym,scale,graph)); 10920 PetscFunctionReturn(0); 10921 } 10922 10923 /*C 10924 MatFilter - filters a Mat values with an absolut value equal to or below a give threshold 10925 10926 Collective on mat 10927 10928 Input Parameter: 10929 . value - filter value - < 0: does nothing; == 0: removes only 0.0 entries; otherwise: removes entries <= value 10930 10931 Input/Output Parameter: 10932 . A - the Mat to filter in place 10933 10934 Level: advanced 10935 10936 Notes: 10937 10938 .seealso: `MatCreate()`, `MatCreateGraph()` 10939 */ 10940 PETSC_EXTERN PetscErrorCode MatFilter(Mat G,PetscReal value,Mat *F) 10941 { 10942 PetscFunctionBegin; 10943 PetscValidHeaderSpecific(G,MAT_CLASSID,1); 10944 PetscValidType(G,1); 10945 PetscValidPointer(F,3); 10946 if (value >= 0.0) { 10947 PetscCheck(G->ops->filter,PetscObjectComm((PetscObject)G),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 10948 PetscCall((G->ops->filter)(G,value,F)); 10949 } 10950 PetscFunctionReturn(0); 10951 } 10952