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