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