1 /* 2 This is where the abstract matrix operations are defined 3 */ 4 5 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 6 #include <petsc/private/isimpl.h> 7 #include <petsc/private/vecimpl.h> 8 9 /* Logging support */ 10 PetscClassId MAT_CLASSID; 11 PetscClassId MAT_COLORING_CLASSID; 12 PetscClassId MAT_FDCOLORING_CLASSID; 13 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 14 15 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultAdd, MAT_MultTranspose; 16 PetscLogEvent MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 17 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 18 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 19 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 20 PetscLogEvent MAT_QRFactorNumeric, MAT_QRFactorSymbolic, MAT_QRFactor; 21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat; 24 PetscLogEvent MAT_TransposeColoringCreate; 25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols; 32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 34 PetscLogEvent MAT_GetMultiProcBlock; 35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_CUSPARSECopyFromGPU, MAT_CUSPARSEGenerateTranspose, MAT_CUSPARSESolveAnalysis; 36 PetscLogEvent MAT_PreallCOO, MAT_SetVCOO; 37 PetscLogEvent MAT_SetValuesBatch; 38 PetscLogEvent MAT_ViennaCLCopyToGPU; 39 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU; 40 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 41 PetscLogEvent MAT_FactorFactS,MAT_FactorInvS; 42 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 43 PetscLogEvent MAT_H2Opus_Build,MAT_H2Opus_Compress,MAT_H2Opus_Orthog,MAT_H2Opus_LR; 44 45 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","QR","MatFactorType","MAT_FACTOR_",NULL}; 46 47 /*@ 48 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations, 49 for sparse matrices that already have locations it fills the locations with random numbers 50 51 Logically Collective on Mat 52 53 Input Parameters: 54 + x - the matrix 55 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 56 it will create one internally. 57 58 Output Parameter: 59 . x - the matrix 60 61 Example of Usage: 62 .vb 63 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 64 MatSetRandom(x,rctx); 65 PetscRandomDestroy(rctx); 66 .ve 67 68 Level: intermediate 69 70 .seealso: `MatZeroEntries()`, `MatSetValues()`, `PetscRandomCreate()`, `PetscRandomDestroy()` 71 @*/ 72 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 73 { 74 PetscRandom randObj = NULL; 75 76 PetscFunctionBegin; 77 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 78 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 79 PetscValidType(x,1); 80 MatCheckPreallocated(x,1); 81 82 PetscCheck(x->ops->setrandom,PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 83 84 if (!rctx) { 85 MPI_Comm comm; 86 PetscCall(PetscObjectGetComm((PetscObject)x,&comm)); 87 PetscCall(PetscRandomCreate(comm,&randObj)); 88 PetscCall(PetscRandomSetFromOptions(randObj)); 89 rctx = randObj; 90 } 91 PetscCall(PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0)); 92 PetscCall((*x->ops->setrandom)(x,rctx)); 93 PetscCall(PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0)); 94 95 PetscCall(MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY)); 96 PetscCall(MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY)); 97 PetscCall(PetscRandomDestroy(&randObj)); 98 PetscFunctionReturn(0); 99 } 100 101 /*@ 102 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 103 104 Logically Collective on Mat 105 106 Input Parameter: 107 . mat - the factored matrix 108 109 Output Parameters: 110 + pivot - the pivot value computed 111 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 112 the share the matrix 113 114 Level: advanced 115 116 Notes: 117 This routine does not work for factorizations done with external packages. 118 119 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 120 121 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 122 123 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()` 124 @*/ 125 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 126 { 127 PetscFunctionBegin; 128 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 129 PetscValidRealPointer(pivot,2); 130 PetscValidIntPointer(row,3); 131 *pivot = mat->factorerror_zeropivot_value; 132 *row = mat->factorerror_zeropivot_row; 133 PetscFunctionReturn(0); 134 } 135 136 /*@ 137 MatFactorGetError - gets the error code from a factorization 138 139 Logically Collective on Mat 140 141 Input Parameters: 142 . mat - the factored matrix 143 144 Output Parameter: 145 . err - the error code 146 147 Level: advanced 148 149 Notes: 150 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 151 152 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorClearError()`, `MatFactorGetErrorZeroPivot()` 153 @*/ 154 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 155 { 156 PetscFunctionBegin; 157 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 158 PetscValidPointer(err,2); 159 *err = mat->factorerrortype; 160 PetscFunctionReturn(0); 161 } 162 163 /*@ 164 MatFactorClearError - clears the error code in a factorization 165 166 Logically Collective on Mat 167 168 Input Parameter: 169 . mat - the factored matrix 170 171 Level: developer 172 173 Notes: 174 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 175 176 .seealso: `MatZeroEntries()`, `MatFactor()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()`, `MatFactorGetError()`, `MatFactorGetErrorZeroPivot()` 177 @*/ 178 PetscErrorCode MatFactorClearError(Mat mat) 179 { 180 PetscFunctionBegin; 181 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 182 mat->factorerrortype = MAT_FACTOR_NOERROR; 183 mat->factorerror_zeropivot_value = 0.0; 184 mat->factorerror_zeropivot_row = 0; 185 PetscFunctionReturn(0); 186 } 187 188 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 189 { 190 Vec r,l; 191 const PetscScalar *al; 192 PetscInt i,nz,gnz,N,n; 193 194 PetscFunctionBegin; 195 PetscCall(MatCreateVecs(mat,&r,&l)); 196 if (!cols) { /* nonzero rows */ 197 PetscCall(MatGetSize(mat,&N,NULL)); 198 PetscCall(MatGetLocalSize(mat,&n,NULL)); 199 PetscCall(VecSet(l,0.0)); 200 PetscCall(VecSetRandom(r,NULL)); 201 PetscCall(MatMult(mat,r,l)); 202 PetscCall(VecGetArrayRead(l,&al)); 203 } else { /* nonzero columns */ 204 PetscCall(MatGetSize(mat,NULL,&N)); 205 PetscCall(MatGetLocalSize(mat,NULL,&n)); 206 PetscCall(VecSet(r,0.0)); 207 PetscCall(VecSetRandom(l,NULL)); 208 PetscCall(MatMultTranspose(mat,l,r)); 209 PetscCall(VecGetArrayRead(r,&al)); 210 } 211 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 212 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 213 PetscCall(MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 214 if (gnz != N) { 215 PetscInt *nzr; 216 PetscCall(PetscMalloc1(nz,&nzr)); 217 if (nz) { 218 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 219 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 220 } 221 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero)); 222 } else *nonzero = NULL; 223 if (!cols) { /* nonzero rows */ 224 PetscCall(VecRestoreArrayRead(l,&al)); 225 } else { 226 PetscCall(VecRestoreArrayRead(r,&al)); 227 } 228 PetscCall(VecDestroy(&l)); 229 PetscCall(VecDestroy(&r)); 230 PetscFunctionReturn(0); 231 } 232 233 /*@ 234 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 235 236 Input Parameter: 237 . A - the matrix 238 239 Output Parameter: 240 . keptrows - the rows that are not completely zero 241 242 Notes: 243 keptrows is set to NULL if all rows are nonzero. 244 245 Level: intermediate 246 247 @*/ 248 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 249 { 250 PetscFunctionBegin; 251 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 252 PetscValidType(mat,1); 253 PetscValidPointer(keptrows,2); 254 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 255 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 256 if (mat->ops->findnonzerorows) { 257 PetscCall((*mat->ops->findnonzerorows)(mat,keptrows)); 258 } else { 259 PetscCall(MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows)); 260 } 261 PetscFunctionReturn(0); 262 } 263 264 /*@ 265 MatFindZeroRows - Locate all rows that are completely zero in the matrix 266 267 Input Parameter: 268 . A - the matrix 269 270 Output Parameter: 271 . zerorows - the rows that are completely zero 272 273 Notes: 274 zerorows is set to NULL if no rows are zero. 275 276 Level: intermediate 277 278 @*/ 279 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 280 { 281 IS keptrows; 282 PetscInt m, n; 283 284 PetscFunctionBegin; 285 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 286 PetscValidType(mat,1); 287 PetscValidPointer(zerorows,2); 288 PetscCall(MatFindNonzeroRows(mat, &keptrows)); 289 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 290 In keeping with this convention, we set zerorows to NULL if there are no zero 291 rows. */ 292 if (keptrows == NULL) { 293 *zerorows = NULL; 294 } else { 295 PetscCall(MatGetOwnershipRange(mat,&m,&n)); 296 PetscCall(ISComplement(keptrows,m,n,zerorows)); 297 PetscCall(ISDestroy(&keptrows)); 298 } 299 PetscFunctionReturn(0); 300 } 301 302 /*@ 303 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 304 305 Not Collective 306 307 Input Parameters: 308 . A - the matrix 309 310 Output Parameters: 311 . a - the diagonal part (which is a SEQUENTIAL matrix) 312 313 Notes: 314 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 315 Use caution, as the reference count on the returned matrix is not incremented and it is used as 316 part of the containing MPI Mat's normal operation. 317 318 Level: advanced 319 320 @*/ 321 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 322 { 323 PetscFunctionBegin; 324 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 325 PetscValidType(A,1); 326 PetscValidPointer(a,2); 327 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 328 if (A->ops->getdiagonalblock) { 329 PetscCall((*A->ops->getdiagonalblock)(A,a)); 330 } else { 331 PetscMPIInt size; 332 333 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A),&size)); 334 PetscCheck(size == 1,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not for parallel matrix type %s",((PetscObject)A)->type_name); 335 *a = A; 336 } 337 PetscFunctionReturn(0); 338 } 339 340 /*@ 341 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 342 343 Collective on Mat 344 345 Input Parameters: 346 . mat - the matrix 347 348 Output Parameter: 349 . trace - the sum of the diagonal entries 350 351 Level: advanced 352 353 @*/ 354 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 355 { 356 Vec diag; 357 358 PetscFunctionBegin; 359 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 360 PetscValidScalarPointer(trace,2); 361 PetscCall(MatCreateVecs(mat,&diag,NULL)); 362 PetscCall(MatGetDiagonal(mat,diag)); 363 PetscCall(VecSum(diag,trace)); 364 PetscCall(VecDestroy(&diag)); 365 PetscFunctionReturn(0); 366 } 367 368 /*@ 369 MatRealPart - Zeros out the imaginary part of the matrix 370 371 Logically Collective on Mat 372 373 Input Parameters: 374 . mat - the matrix 375 376 Level: advanced 377 378 .seealso: `MatImaginaryPart()` 379 @*/ 380 PetscErrorCode MatRealPart(Mat mat) 381 { 382 PetscFunctionBegin; 383 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 384 PetscValidType(mat,1); 385 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 386 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 387 PetscCheck(mat->ops->realpart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 388 MatCheckPreallocated(mat,1); 389 PetscCall((*mat->ops->realpart)(mat)); 390 PetscFunctionReturn(0); 391 } 392 393 /*@C 394 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 395 396 Collective on Mat 397 398 Input Parameter: 399 . mat - the matrix 400 401 Output Parameters: 402 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 403 - ghosts - the global indices of the ghost points 404 405 Notes: 406 the nghosts and ghosts are suitable to pass into VecCreateGhost() 407 408 Level: advanced 409 410 @*/ 411 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 412 { 413 PetscFunctionBegin; 414 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 415 PetscValidType(mat,1); 416 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 417 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 418 if (mat->ops->getghosts) { 419 PetscCall((*mat->ops->getghosts)(mat,nghosts,ghosts)); 420 } else { 421 if (nghosts) *nghosts = 0; 422 if (ghosts) *ghosts = NULL; 423 } 424 PetscFunctionReturn(0); 425 } 426 427 /*@ 428 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 429 430 Logically Collective on Mat 431 432 Input Parameters: 433 . mat - the matrix 434 435 Level: advanced 436 437 .seealso: `MatRealPart()` 438 @*/ 439 PetscErrorCode MatImaginaryPart(Mat mat) 440 { 441 PetscFunctionBegin; 442 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 443 PetscValidType(mat,1); 444 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 445 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 446 PetscCheck(mat->ops->imaginarypart,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 447 MatCheckPreallocated(mat,1); 448 PetscCall((*mat->ops->imaginarypart)(mat)); 449 PetscFunctionReturn(0); 450 } 451 452 /*@ 453 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 454 455 Not Collective 456 457 Input Parameter: 458 . mat - the matrix 459 460 Output Parameters: 461 + missing - is any diagonal missing 462 - dd - first diagonal entry that is missing (optional) on this process 463 464 Level: advanced 465 466 .seealso: `MatRealPart()` 467 @*/ 468 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 469 { 470 PetscFunctionBegin; 471 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 472 PetscValidType(mat,1); 473 PetscValidBoolPointer(missing,2); 474 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name); 475 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 476 PetscCheck(mat->ops->missingdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 477 PetscCall((*mat->ops->missingdiagonal)(mat,missing,dd)); 478 PetscFunctionReturn(0); 479 } 480 481 /*@C 482 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 483 for each row that you get to ensure that your application does 484 not bleed memory. 485 486 Not Collective 487 488 Input Parameters: 489 + mat - the matrix 490 - row - the row to get 491 492 Output Parameters: 493 + ncols - if not NULL, the number of nonzeros in the row 494 . cols - if not NULL, the column numbers 495 - vals - if not NULL, the values 496 497 Notes: 498 This routine is provided for people who need to have direct access 499 to the structure of a matrix. We hope that we provide enough 500 high-level matrix routines that few users will need it. 501 502 MatGetRow() always returns 0-based column indices, regardless of 503 whether the internal representation is 0-based (default) or 1-based. 504 505 For better efficiency, set cols and/or vals to NULL if you do 506 not wish to extract these quantities. 507 508 The user can only examine the values extracted with MatGetRow(); 509 the values cannot be altered. To change the matrix entries, one 510 must use MatSetValues(). 511 512 You can only have one call to MatGetRow() outstanding for a particular 513 matrix at a time, per processor. MatGetRow() can only obtain rows 514 associated with the given processor, it cannot get rows from the 515 other processors; for that we suggest using MatCreateSubMatrices(), then 516 MatGetRow() on the submatrix. The row index passed to MatGetRow() 517 is in the global number of rows. 518 519 Fortran Notes: 520 The calling sequence from Fortran is 521 .vb 522 MatGetRow(matrix,row,ncols,cols,values,ierr) 523 Mat matrix (input) 524 integer row (input) 525 integer ncols (output) 526 integer cols(maxcols) (output) 527 double precision (or double complex) values(maxcols) output 528 .ve 529 where maxcols >= maximum nonzeros in any row of the matrix. 530 531 Caution: 532 Do not try to change the contents of the output arrays (cols and vals). 533 In some cases, this may corrupt the matrix. 534 535 Level: advanced 536 537 .seealso: `MatRestoreRow()`, `MatSetValues()`, `MatGetValues()`, `MatCreateSubMatrices()`, `MatGetDiagonal()` 538 @*/ 539 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 540 { 541 PetscInt incols; 542 543 PetscFunctionBegin; 544 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 545 PetscValidType(mat,1); 546 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 547 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 548 PetscCheck(mat->ops->getrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 549 MatCheckPreallocated(mat,1); 550 PetscCheck(row >= mat->rmap->rstart && row < mat->rmap->rend,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Only for local rows, %" PetscInt_FMT " not in [%" PetscInt_FMT ",%" PetscInt_FMT ")",row,mat->rmap->rstart,mat->rmap->rend); 551 PetscCall(PetscLogEventBegin(MAT_GetRow,mat,0,0,0)); 552 PetscCall((*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals)); 553 if (ncols) *ncols = incols; 554 PetscCall(PetscLogEventEnd(MAT_GetRow,mat,0,0,0)); 555 PetscFunctionReturn(0); 556 } 557 558 /*@ 559 MatConjugate - replaces the matrix values with their complex conjugates 560 561 Logically Collective on Mat 562 563 Input Parameters: 564 . mat - the matrix 565 566 Level: advanced 567 568 .seealso: `VecConjugate()` 569 @*/ 570 PetscErrorCode MatConjugate(Mat mat) 571 { 572 PetscFunctionBegin; 573 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 574 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 575 if (PetscDefined(USE_COMPLEX)) { 576 PetscCheck(mat->ops->conjugate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for matrix type %s, send email to petsc-maint@mcs.anl.gov",((PetscObject)mat)->type_name); 577 PetscCall((*mat->ops->conjugate)(mat)); 578 } 579 PetscFunctionReturn(0); 580 } 581 582 /*@C 583 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 584 585 Not Collective 586 587 Input Parameters: 588 + mat - the matrix 589 . row - the row to get 590 . ncols, cols - the number of nonzeros and their columns 591 - vals - if nonzero the column values 592 593 Notes: 594 This routine should be called after you have finished examining the entries. 595 596 This routine zeros out ncols, cols, and vals. This is to prevent accidental 597 us of the array after it has been restored. If you pass NULL, it will 598 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 599 600 Fortran Notes: 601 The calling sequence from Fortran is 602 .vb 603 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 604 Mat matrix (input) 605 integer row (input) 606 integer ncols (output) 607 integer cols(maxcols) (output) 608 double precision (or double complex) values(maxcols) output 609 .ve 610 Where maxcols >= maximum nonzeros in any row of the matrix. 611 612 In Fortran MatRestoreRow() MUST be called after MatGetRow() 613 before another call to MatGetRow() can be made. 614 615 Level: advanced 616 617 .seealso: `MatGetRow()` 618 @*/ 619 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 620 { 621 PetscFunctionBegin; 622 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 623 if (ncols) PetscValidIntPointer(ncols,3); 624 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 625 if (!mat->ops->restorerow) PetscFunctionReturn(0); 626 PetscCall((*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals)); 627 if (ncols) *ncols = 0; 628 if (cols) *cols = NULL; 629 if (vals) *vals = NULL; 630 PetscFunctionReturn(0); 631 } 632 633 /*@ 634 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 635 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 636 637 Not Collective 638 639 Input Parameters: 640 . mat - the matrix 641 642 Notes: 643 The flag is to ensure that users are aware of MatGetRow() only provides the upper triangular part of the row for the matrices in MATSBAIJ format. 644 645 Level: advanced 646 647 .seealso: `MatRestoreRowUpperTriangular()` 648 @*/ 649 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 650 { 651 PetscFunctionBegin; 652 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 653 PetscValidType(mat,1); 654 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 655 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 656 MatCheckPreallocated(mat,1); 657 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 658 PetscCall((*mat->ops->getrowuppertriangular)(mat)); 659 PetscFunctionReturn(0); 660 } 661 662 /*@ 663 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 664 665 Not Collective 666 667 Input Parameters: 668 . mat - the matrix 669 670 Notes: 671 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 672 673 Level: advanced 674 675 .seealso: `MatGetRowUpperTriangular()` 676 @*/ 677 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 678 { 679 PetscFunctionBegin; 680 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 681 PetscValidType(mat,1); 682 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 683 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 684 MatCheckPreallocated(mat,1); 685 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 686 PetscCall((*mat->ops->restorerowuppertriangular)(mat)); 687 PetscFunctionReturn(0); 688 } 689 690 /*@C 691 MatSetOptionsPrefix - Sets the prefix used for searching for all 692 Mat options in the database. 693 694 Logically Collective on Mat 695 696 Input Parameters: 697 + A - the Mat context 698 - prefix - the prefix to prepend to all option names 699 700 Notes: 701 A hyphen (-) must NOT be given at the beginning of the prefix name. 702 The first character of all runtime options is AUTOMATICALLY the hyphen. 703 704 This is NOT used for options for the factorization of the matrix. Normally the 705 prefix is automatically passed in from the PC calling the factorization. To set 706 it directly use `MatSetOptionsPrefixFactor()` 707 708 Level: advanced 709 710 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefixFactor()` 711 @*/ 712 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 713 { 714 PetscFunctionBegin; 715 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 716 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)A,prefix)); 717 PetscFunctionReturn(0); 718 } 719 720 /*@C 721 MatSetOptionsPrefixFactor - Sets the prefix used for searching for all Mat factor options in the database for 722 for matrices created with `MatGetFactor()` 723 724 Logically Collective on Mat 725 726 Input Parameters: 727 + A - the Mat context 728 - prefix - the prefix to prepend to all option names for the factored matrix 729 730 Notes: 731 A hyphen (-) must NOT be given at the beginning of the prefix name. 732 The first character of all runtime options is AUTOMATICALLY the hyphen. 733 734 Normally the prefix is automatically passed in from the PC calling the factorization. To set 735 it directly when not using `KSP`/`PC` use `MatSetOptionsPrefixFactor()` 736 737 Level: developer 738 739 .seealso: `MatSetFromOptions()`, `MatSetOptionsPrefix()`, `MatAppendOptionsPrefixFactor()` 740 @*/ 741 PetscErrorCode MatSetOptionsPrefixFactor(Mat A,const char prefix[]) 742 { 743 PetscFunctionBegin; 744 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 745 if (prefix) { 746 PetscValidCharPointer(prefix,2); 747 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 748 if (prefix != A->factorprefix) { 749 PetscCall(PetscFree(A->factorprefix)); 750 PetscCall(PetscStrallocpy(prefix,&A->factorprefix)); 751 } 752 } else PetscCall(PetscFree(A->factorprefix)); 753 PetscFunctionReturn(0); 754 } 755 756 /*@C 757 MatAppendOptionsPrefixFactor - Appends to the prefix used for searching for all Mat factor options in the database for 758 for matrices created with `MatGetFactor()` 759 760 Logically Collective on Mat 761 762 Input Parameters: 763 + A - the Mat context 764 - prefix - the prefix to prepend to all option names for the factored matrix 765 766 Notes: 767 A hyphen (-) must NOT be given at the beginning of the prefix name. 768 The first character of all runtime options is AUTOMATICALLY the hyphen. 769 770 Normally the prefix is automatically passed in from the PC calling the factorization. To set 771 it directly when not using `KSP`/`PC` use `MatAppendOptionsPrefixFactor()` 772 773 Level: developer 774 .seealso: `PetscOptionsCreate()`, `PetscOptionsDestroy()`, `PetscObjectSetOptionsPrefix()`, `PetscObjectPrependOptionsPrefix()`, 775 `PetscObjectGetOptionsPrefix()`, `TSAppendOptionsPrefix()`, `SNESAppendOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `MatSetOptionsPrefixFactor()`, 776 `MatSetOptionsPrefix()` 777 @*/ 778 PetscErrorCode MatAppendOptionsPrefixFactor(Mat A,const char prefix[]) 779 { 780 char *buf = A->factorprefix; 781 size_t len1,len2; 782 783 PetscFunctionBegin; 784 PetscValidHeader(A,1); 785 if (!prefix) PetscFunctionReturn(0); 786 if (!buf) { 787 PetscCall(MatSetOptionsPrefixFactor(A,prefix)); 788 PetscFunctionReturn(0); 789 } 790 PetscCheck(prefix[0] != '-',PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen"); 791 792 PetscCall(PetscStrlen(prefix,&len1)); 793 PetscCall(PetscStrlen(buf,&len2)); 794 PetscCall(PetscMalloc1(1+len1+len2,&A->factorprefix)); 795 PetscCall(PetscStrcpy(A->factorprefix,buf)); 796 PetscCall(PetscStrcat(A->factorprefix,prefix)); 797 PetscCall(PetscFree(buf)); 798 PetscFunctionReturn(0); 799 } 800 801 /*@C 802 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 803 Mat options in the database. 804 805 Logically Collective on Mat 806 807 Input Parameters: 808 + A - the Mat context 809 - prefix - the prefix to prepend to all option names 810 811 Notes: 812 A hyphen (-) must NOT be given at the beginning of the prefix name. 813 The first character of all runtime options is AUTOMATICALLY the hyphen. 814 815 Level: advanced 816 817 .seealso: `MatGetOptionsPrefix()` 818 @*/ 819 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 820 { 821 PetscFunctionBegin; 822 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 823 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)A,prefix)); 824 PetscFunctionReturn(0); 825 } 826 827 /*@C 828 MatGetOptionsPrefix - Gets the prefix used for searching for all 829 Mat options in the database. 830 831 Not Collective 832 833 Input Parameter: 834 . A - the Mat context 835 836 Output Parameter: 837 . prefix - pointer to the prefix string used 838 839 Notes: 840 On the fortran side, the user should pass in a string 'prefix' of 841 sufficient length to hold the prefix. 842 843 Level: advanced 844 845 .seealso: `MatAppendOptionsPrefix()` 846 @*/ 847 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 848 { 849 PetscFunctionBegin; 850 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 851 PetscValidPointer(prefix,2); 852 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)A,prefix)); 853 PetscFunctionReturn(0); 854 } 855 856 /*@ 857 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 858 859 Collective on Mat 860 861 Input Parameters: 862 . A - the Mat context 863 864 Notes: 865 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 866 Currently support MPIAIJ and SEQAIJ. 867 868 Level: beginner 869 870 .seealso: `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatXAIJSetPreallocation()` 871 @*/ 872 PetscErrorCode MatResetPreallocation(Mat A) 873 { 874 PetscFunctionBegin; 875 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 876 PetscValidType(A,1); 877 PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A)); 878 PetscFunctionReturn(0); 879 } 880 881 /*@ 882 MatSetUp - Sets up the internal matrix data structures for later use. 883 884 Collective on Mat 885 886 Input Parameters: 887 . A - the Mat context 888 889 Notes: 890 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 891 892 If a suitable preallocation routine is used, this function does not need to be called. 893 894 See the Performance chapter of the PETSc users manual for how to preallocate matrices 895 896 Level: beginner 897 898 .seealso: `MatCreate()`, `MatDestroy()` 899 @*/ 900 PetscErrorCode MatSetUp(Mat A) 901 { 902 PetscFunctionBegin; 903 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 904 if (!((PetscObject)A)->type_name) { 905 PetscMPIInt size; 906 907 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 908 PetscCall(MatSetType(A, size == 1 ? MATSEQAIJ : MATMPIAIJ)); 909 } 910 if (!A->preallocated && A->ops->setup) { 911 PetscCall(PetscInfo(A,"Warning not preallocating matrix storage\n")); 912 PetscCall((*A->ops->setup)(A)); 913 } 914 PetscCall(PetscLayoutSetUp(A->rmap)); 915 PetscCall(PetscLayoutSetUp(A->cmap)); 916 A->preallocated = PETSC_TRUE; 917 PetscFunctionReturn(0); 918 } 919 920 #if defined(PETSC_HAVE_SAWS) 921 #include <petscviewersaws.h> 922 #endif 923 924 /*@C 925 MatViewFromOptions - View from Options 926 927 Collective on Mat 928 929 Input Parameters: 930 + A - the Mat context 931 . obj - Optional object 932 - name - command line option 933 934 Level: intermediate 935 .seealso: `Mat`, `MatView`, `PetscObjectViewFromOptions()`, `MatCreate()` 936 @*/ 937 PetscErrorCode MatViewFromOptions(Mat A,PetscObject obj,const char name[]) 938 { 939 PetscFunctionBegin; 940 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 941 PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 942 PetscFunctionReturn(0); 943 } 944 945 /*@C 946 MatView - Visualizes a matrix object. 947 948 Collective on Mat 949 950 Input Parameters: 951 + mat - the matrix 952 - viewer - visualization context 953 954 Notes: 955 The available visualization contexts include 956 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 957 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 958 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 959 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 960 961 The user can open alternative visualization contexts with 962 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 963 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 964 specified file; corresponding input uses MatLoad() 965 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 966 an X window display 967 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 968 Currently only the sequential dense and AIJ 969 matrix types support the Socket viewer. 970 971 The user can call PetscViewerPushFormat() to specify the output 972 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 973 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 974 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 975 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 976 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 977 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 978 format common among all matrix types 979 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 980 format (which is in many cases the same as the default) 981 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 982 size and structure (not the matrix entries) 983 - PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 984 the matrix structure 985 986 Options Database Keys: 987 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 988 . -mat_view ::ascii_info_detail - Prints more detailed info 989 . -mat_view - Prints matrix in ASCII format 990 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 991 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 992 . -display <name> - Sets display name (default is host) 993 . -draw_pause <sec> - Sets number of seconds to pause after display 994 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 995 . -viewer_socket_machine <machine> - 996 . -viewer_socket_port <port> - 997 . -mat_view binary - save matrix to file in binary format 998 - -viewer_binary_filename <name> - 999 1000 Level: beginner 1001 1002 Notes: 1003 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 1004 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 1005 1006 In the debugger you can do "call MatView(mat,0)" to display the matrix. (The same holds for any PETSc object viewer). 1007 1008 See the manual page for MatLoad() for the exact format of the binary file when the binary 1009 viewer is used. 1010 1011 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 1012 viewer is used and lib/petsc/bin/PetscBinaryIO.py for loading them into Python. 1013 1014 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 1015 and then use the following mouse functions. 1016 .vb 1017 left mouse: zoom in 1018 middle mouse: zoom out 1019 right mouse: continue with the simulation 1020 .ve 1021 1022 .seealso: `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, 1023 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `MatLoad()` 1024 @*/ 1025 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 1026 { 1027 PetscInt rows,cols,rbs,cbs; 1028 PetscBool isascii,isstring,issaws; 1029 PetscViewerFormat format; 1030 PetscMPIInt size; 1031 1032 PetscFunctionBegin; 1033 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1034 PetscValidType(mat,1); 1035 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer)); 1036 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1037 PetscCheckSameComm(mat,1,viewer,2); 1038 MatCheckPreallocated(mat,1); 1039 1040 PetscCall(PetscViewerGetFormat(viewer,&format)); 1041 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 1042 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 1043 1044 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring)); 1045 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii)); 1046 PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws)); 1047 if ((!isascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1048 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detail"); 1049 } 1050 1051 PetscCall(PetscLogEventBegin(MAT_View,mat,viewer,0,0)); 1052 if (isascii) { 1053 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1054 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer)); 1055 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1056 MatNullSpace nullsp,transnullsp; 1057 1058 PetscCall(PetscViewerASCIIPushTab(viewer)); 1059 PetscCall(MatGetSize(mat,&rows,&cols)); 1060 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1061 if (rbs != 1 || cbs != 1) { 1062 if (rbs != cbs) PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", rbs=%" PetscInt_FMT ", cbs=%" PetscInt_FMT "\n",rows,cols,rbs,cbs)); 1063 else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n",rows,cols,rbs)); 1064 } else PetscCall(PetscViewerASCIIPrintf(viewer,"rows=%" PetscInt_FMT ", cols=%" PetscInt_FMT "\n",rows,cols)); 1065 if (mat->factortype) { 1066 MatSolverType solver; 1067 PetscCall(MatFactorGetSolverType(mat,&solver)); 1068 PetscCall(PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver)); 1069 } 1070 if (mat->ops->getinfo) { 1071 MatInfo info; 1072 PetscCall(MatGetInfo(mat,MAT_GLOBAL_SUM,&info)); 1073 PetscCall(PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated)); 1074 if (!mat->factortype) PetscCall(PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%" PetscInt_FMT "\n",(PetscInt)info.mallocs)); 1075 } 1076 PetscCall(MatGetNullSpace(mat,&nullsp)); 1077 PetscCall(MatGetTransposeNullSpace(mat,&transnullsp)); 1078 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached null space\n")); 1079 if (transnullsp && transnullsp != nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached transposed null space\n")); 1080 PetscCall(MatGetNearNullSpace(mat,&nullsp)); 1081 if (nullsp) PetscCall(PetscViewerASCIIPrintf(viewer," has attached near null space\n")); 1082 PetscCall(PetscViewerASCIIPushTab(viewer)); 1083 PetscCall(MatProductView(mat,viewer)); 1084 PetscCall(PetscViewerASCIIPopTab(viewer)); 1085 } 1086 } else if (issaws) { 1087 #if defined(PETSC_HAVE_SAWS) 1088 PetscMPIInt rank; 1089 1090 PetscCall(PetscObjectName((PetscObject)mat)); 1091 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 1092 if (!((PetscObject)mat)->amsmem && rank == 0) { 1093 PetscCall(PetscObjectViewSAWs((PetscObject)mat,viewer)); 1094 } 1095 #endif 1096 } else if (isstring) { 1097 const char *type; 1098 PetscCall(MatGetType(mat,&type)); 1099 PetscCall(PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type)); 1100 if (mat->ops->view) PetscCall((*mat->ops->view)(mat,viewer)); 1101 } 1102 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1103 PetscCall(PetscViewerASCIIPushTab(viewer)); 1104 PetscCall((*mat->ops->viewnative)(mat,viewer)); 1105 PetscCall(PetscViewerASCIIPopTab(viewer)); 1106 } else if (mat->ops->view) { 1107 PetscCall(PetscViewerASCIIPushTab(viewer)); 1108 PetscCall((*mat->ops->view)(mat,viewer)); 1109 PetscCall(PetscViewerASCIIPopTab(viewer)); 1110 } 1111 if (isascii) { 1112 PetscCall(PetscViewerGetFormat(viewer,&format)); 1113 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1114 PetscCall(PetscViewerASCIIPopTab(viewer)); 1115 } 1116 } 1117 PetscCall(PetscLogEventEnd(MAT_View,mat,viewer,0,0)); 1118 PetscFunctionReturn(0); 1119 } 1120 1121 #if defined(PETSC_USE_DEBUG) 1122 #include <../src/sys/totalview/tv_data_display.h> 1123 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1124 { 1125 TV_add_row("Local rows", "int", &mat->rmap->n); 1126 TV_add_row("Local columns", "int", &mat->cmap->n); 1127 TV_add_row("Global rows", "int", &mat->rmap->N); 1128 TV_add_row("Global columns", "int", &mat->cmap->N); 1129 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1130 return TV_format_OK; 1131 } 1132 #endif 1133 1134 /*@C 1135 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1136 with MatView(). The matrix format is determined from the options database. 1137 Generates a parallel MPI matrix if the communicator has more than one 1138 processor. The default matrix type is AIJ. 1139 1140 Collective on PetscViewer 1141 1142 Input Parameters: 1143 + mat - the newly loaded matrix, this needs to have been created with MatCreate() 1144 or some related function before a call to MatLoad() 1145 - viewer - binary/HDF5 file viewer 1146 1147 Options Database Keys: 1148 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1149 block size 1150 . -matload_block_size <bs> - set block size 1151 1152 Level: beginner 1153 1154 Notes: 1155 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1156 Mat before calling this routine if you wish to set it from the options database. 1157 1158 MatLoad() automatically loads into the options database any options 1159 given in the file filename.info where filename is the name of the file 1160 that was passed to the PetscViewerBinaryOpen(). The options in the info 1161 file will be ignored if you use the -viewer_binary_skip_info option. 1162 1163 If the type or size of mat is not set before a call to MatLoad, PETSc 1164 sets the default matrix type AIJ and sets the local and global sizes. 1165 If type and/or size is already set, then the same are used. 1166 1167 In parallel, each processor can load a subset of rows (or the 1168 entire matrix). This routine is especially useful when a large 1169 matrix is stored on disk and only part of it is desired on each 1170 processor. For example, a parallel solver may access only some of 1171 the rows from each processor. The algorithm used here reads 1172 relatively small blocks of data rather than reading the entire 1173 matrix and then subsetting it. 1174 1175 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5. 1176 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(), 1177 or the sequence like 1178 $ PetscViewer v; 1179 $ PetscViewerCreate(PETSC_COMM_WORLD,&v); 1180 $ PetscViewerSetType(v,PETSCVIEWERBINARY); 1181 $ PetscViewerSetFromOptions(v); 1182 $ PetscViewerFileSetMode(v,FILE_MODE_READ); 1183 $ PetscViewerFileSetName(v,"datafile"); 1184 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option 1185 $ -viewer_type {binary,hdf5} 1186 1187 See the example src/ksp/ksp/tutorials/ex27.c with the first approach, 1188 and src/mat/tutorials/ex10.c with the second approach. 1189 1190 Notes about the PETSc binary format: 1191 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks 1192 is read onto rank 0 and then shipped to its destination rank, one after another. 1193 Multiple objects, both matrices and vectors, can be stored within the same file. 1194 Their PetscObject name is ignored; they are loaded in the order of their storage. 1195 1196 Most users should not need to know the details of the binary storage 1197 format, since MatLoad() and MatView() completely hide these details. 1198 But for anyone who's interested, the standard binary matrix storage 1199 format is 1200 1201 $ PetscInt MAT_FILE_CLASSID 1202 $ PetscInt number of rows 1203 $ PetscInt number of columns 1204 $ PetscInt total number of nonzeros 1205 $ PetscInt *number nonzeros in each row 1206 $ PetscInt *column indices of all nonzeros (starting index is zero) 1207 $ PetscScalar *values of all nonzeros 1208 1209 PETSc automatically does the byte swapping for 1210 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1211 Linux, Microsoft Windows and the Intel Paragon; thus if you write your own binary 1212 read/write routines you have to swap the bytes; see PetscBinaryRead() 1213 and PetscBinaryWrite() to see how this may be done. 1214 1215 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1216 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used. 1217 Each processor's chunk is loaded independently by its owning rank. 1218 Multiple objects, both matrices and vectors, can be stored within the same file. 1219 They are looked up by their PetscObject name. 1220 1221 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1222 by default the same structure and naming of the AIJ arrays and column count 1223 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1224 $ save example.mat A b -v7.3 1225 can be directly read by this routine (see Reference 1 for details). 1226 Note that depending on your MATLAB version, this format might be a default, 1227 otherwise you can set it as default in Preferences. 1228 1229 Unless -nocompression flag is used to save the file in MATLAB, 1230 PETSc must be configured with ZLIB package. 1231 1232 See also examples src/mat/tutorials/ex10.c and src/ksp/ksp/tutorials/ex27.c 1233 1234 Current HDF5 (MAT-File) limitations: 1235 This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices. 1236 1237 Corresponding MatView() is not yet implemented. 1238 1239 The loaded matrix is actually a transpose of the original one in MATLAB, 1240 unless you push PETSC_VIEWER_HDF5_MAT format (see examples above). 1241 With this format, matrix is automatically transposed by PETSc, 1242 unless the matrix is marked as SPD or symmetric 1243 (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC). 1244 1245 References: 1246 . * - MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1247 1248 .seealso: `PetscViewerBinaryOpen()`, `PetscViewerSetType()`, `MatView()`, `VecLoad()` 1249 1250 @*/ 1251 PetscErrorCode MatLoad(Mat mat,PetscViewer viewer) 1252 { 1253 PetscBool flg; 1254 1255 PetscFunctionBegin; 1256 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1257 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1258 1259 if (!((PetscObject)mat)->type_name) PetscCall(MatSetType(mat,MATAIJ)); 1260 1261 flg = PETSC_FALSE; 1262 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_symmetric",&flg,NULL)); 1263 if (flg) { 1264 PetscCall(MatSetOption(mat,MAT_SYMMETRIC,PETSC_TRUE)); 1265 PetscCall(MatSetOption(mat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE)); 1266 } 1267 flg = PETSC_FALSE; 1268 PetscCall(PetscOptionsGetBool(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matload_spd",&flg,NULL)); 1269 if (flg) PetscCall(MatSetOption(mat,MAT_SPD,PETSC_TRUE)); 1270 1271 PetscCheck(mat->ops->load,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)mat)->type_name); 1272 PetscCall(PetscLogEventBegin(MAT_Load,mat,viewer,0,0)); 1273 PetscCall((*mat->ops->load)(mat,viewer)); 1274 PetscCall(PetscLogEventEnd(MAT_Load,mat,viewer,0,0)); 1275 PetscFunctionReturn(0); 1276 } 1277 1278 static PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1279 { 1280 Mat_Redundant *redund = *redundant; 1281 1282 PetscFunctionBegin; 1283 if (redund) { 1284 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1285 PetscCall(ISDestroy(&redund->isrow)); 1286 PetscCall(ISDestroy(&redund->iscol)); 1287 PetscCall(MatDestroySubMatrices(1,&redund->matseq)); 1288 } else { 1289 PetscCall(PetscFree2(redund->send_rank,redund->recv_rank)); 1290 PetscCall(PetscFree(redund->sbuf_j)); 1291 PetscCall(PetscFree(redund->sbuf_a)); 1292 for (PetscInt i=0; i<redund->nrecvs; i++) { 1293 PetscCall(PetscFree(redund->rbuf_j[i])); 1294 PetscCall(PetscFree(redund->rbuf_a[i])); 1295 } 1296 PetscCall(PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a)); 1297 } 1298 1299 if (redund->subcomm) PetscCall(PetscCommDestroy(&redund->subcomm)); 1300 PetscCall(PetscFree(redund)); 1301 } 1302 PetscFunctionReturn(0); 1303 } 1304 1305 /*@C 1306 MatDestroy - Frees space taken by a matrix. 1307 1308 Collective on Mat 1309 1310 Input Parameter: 1311 . A - the matrix 1312 1313 Level: beginner 1314 1315 Developer Notes: 1316 Some special arrays of matrices are not destroyed in this routine but instead by the routines called by 1317 MatDestroySubMatrices(). Thus one must be sure that any changes here must also be made in those routines. 1318 MatHeaderMerge() and MatHeaderReplace() also manipulate the data in the Mat object and likely need changes 1319 if changes are needed here. 1320 @*/ 1321 PetscErrorCode MatDestroy(Mat *A) 1322 { 1323 PetscFunctionBegin; 1324 if (!*A) PetscFunctionReturn(0); 1325 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1326 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1327 1328 /* if memory was published with SAWs then destroy it */ 1329 PetscCall(PetscObjectSAWsViewOff((PetscObject)*A)); 1330 if ((*A)->ops->destroy) PetscCall((*(*A)->ops->destroy)(*A)); 1331 1332 PetscCall(PetscFree((*A)->factorprefix)); 1333 PetscCall(PetscFree((*A)->defaultvectype)); 1334 PetscCall(PetscFree((*A)->bsizes)); 1335 PetscCall(PetscFree((*A)->solvertype)); 1336 for (PetscInt i=0; i<MAT_FACTOR_NUM_TYPES; i++) PetscCall(PetscFree((*A)->preferredordering[i])); 1337 if ((*A)->redundant && (*A)->redundant->matseq[0] == *A) (*A)->redundant->matseq[0] = NULL; 1338 PetscCall(MatDestroy_Redundant(&(*A)->redundant)); 1339 PetscCall(MatProductClear(*A)); 1340 PetscCall(MatNullSpaceDestroy(&(*A)->nullsp)); 1341 PetscCall(MatNullSpaceDestroy(&(*A)->transnullsp)); 1342 PetscCall(MatNullSpaceDestroy(&(*A)->nearnullsp)); 1343 PetscCall(MatDestroy(&(*A)->schur)); 1344 PetscCall(PetscLayoutDestroy(&(*A)->rmap)); 1345 PetscCall(PetscLayoutDestroy(&(*A)->cmap)); 1346 PetscCall(PetscHeaderDestroy(A)); 1347 PetscFunctionReturn(0); 1348 } 1349 1350 /*@C 1351 MatSetValues - Inserts or adds a block of values into a matrix. 1352 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1353 MUST be called after all calls to MatSetValues() have been completed. 1354 1355 Not Collective 1356 1357 Input Parameters: 1358 + mat - the matrix 1359 . v - a logically two-dimensional array of values 1360 . m, idxm - the number of rows and their global indices 1361 . n, idxn - the number of columns and their global indices 1362 - addv - either ADD_VALUES or INSERT_VALUES, where 1363 ADD_VALUES adds values to any existing entries, and 1364 INSERT_VALUES replaces existing entries with new values 1365 1366 Notes: 1367 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1368 MatSetUp() before using this routine 1369 1370 By default the values, v, are row-oriented. See MatSetOption() for other options. 1371 1372 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1373 options cannot be mixed without intervening calls to the assembly 1374 routines. 1375 1376 MatSetValues() uses 0-based row and column numbers in Fortran 1377 as well as in C. 1378 1379 Negative indices may be passed in idxm and idxn, these rows and columns are 1380 simply ignored. This allows easily inserting element stiffness matrices 1381 with homogeneous Dirchlet boundary conditions that you don't want represented 1382 in the matrix. 1383 1384 Efficiency Alert: 1385 The routine MatSetValuesBlocked() may offer much better efficiency 1386 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1387 1388 Level: beginner 1389 1390 Developer Notes: 1391 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1392 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1393 1394 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1395 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 1396 @*/ 1397 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1398 { 1399 PetscFunctionBeginHot; 1400 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1401 PetscValidType(mat,1); 1402 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1403 PetscValidIntPointer(idxm,3); 1404 PetscValidIntPointer(idxn,5); 1405 MatCheckPreallocated(mat,1); 1406 1407 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1408 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1409 1410 if (PetscDefined(USE_DEBUG)) { 1411 PetscInt i,j; 1412 1413 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1414 PetscCheck(mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1415 1416 for (i=0; i<m; i++) { 1417 for (j=0; j<n; j++) { 1418 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1419 #if defined(PETSC_USE_COMPLEX) 1420 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+i%g at matrix entry (%" PetscInt_FMT ",%" PetscInt_FMT ")",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]); 1421 #else 1422 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%" PetscInt_FMT ",%" PetscInt_FMT ")",(double)v[i*n+j],idxm[i],idxn[j]); 1423 #endif 1424 } 1425 } 1426 for (i=0; i<m; i++) PetscCheck(idxm[i] < mat->rmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in row %" PetscInt_FMT ", maximum is %" PetscInt_FMT,idxm[i],mat->rmap->N-1); 1427 for (i=0; i<n; i++) PetscCheck(idxn[i] < mat->cmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Cannot insert in column %" PetscInt_FMT ", maximum is %" PetscInt_FMT,idxn[i],mat->cmap->N-1); 1428 } 1429 1430 if (mat->assembled) { 1431 mat->was_assembled = PETSC_TRUE; 1432 mat->assembled = PETSC_FALSE; 1433 } 1434 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1435 PetscCall((*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv)); 1436 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1437 PetscFunctionReturn(0); 1438 } 1439 1440 /*@C 1441 MatSetValuesIS - Inserts or adds a block of values into a matrix using IS to indicate the rows and columns 1442 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1443 MUST be called after all calls to MatSetValues() have been completed. 1444 1445 Not Collective 1446 1447 Input Parameters: 1448 + mat - the matrix 1449 . v - a logically two-dimensional array of values 1450 . ism - the rows to provide 1451 . isn - the columns to provide 1452 - addv - either ADD_VALUES or INSERT_VALUES, where 1453 ADD_VALUES adds values to any existing entries, and 1454 INSERT_VALUES replaces existing entries with new values 1455 1456 Notes: 1457 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1458 MatSetUp() before using this routine 1459 1460 By default the values, v, are row-oriented. See MatSetOption() for other options. 1461 1462 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1463 options cannot be mixed without intervening calls to the assembly 1464 routines. 1465 1466 MatSetValues() uses 0-based row and column numbers in Fortran 1467 as well as in C. 1468 1469 Negative indices may be passed in ism and isn, these rows and columns are 1470 simply ignored. This allows easily inserting element stiffness matrices 1471 with homogeneous Dirchlet boundary conditions that you don't want represented 1472 in the matrix. 1473 1474 Efficiency Alert: 1475 The routine MatSetValuesBlocked() may offer much better efficiency 1476 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1477 1478 Level: beginner 1479 1480 Developer Notes: 1481 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1482 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1483 1484 This is currently not optimized for any particular IS type 1485 1486 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1487 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1488 @*/ 1489 PetscErrorCode MatSetValuesIS(Mat mat,IS ism,IS isn,const PetscScalar v[],InsertMode addv) 1490 { 1491 PetscInt m,n; 1492 const PetscInt *rows,*cols; 1493 1494 PetscFunctionBeginHot; 1495 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1496 PetscCall(ISGetIndices(ism,&rows)); 1497 PetscCall(ISGetIndices(isn,&cols)); 1498 PetscCall(ISGetLocalSize(ism,&m)); 1499 PetscCall(ISGetLocalSize(isn,&n)); 1500 PetscCall(MatSetValues(mat,m,rows,n,cols,v,addv)); 1501 PetscCall(ISRestoreIndices(ism,&rows)); 1502 PetscCall(ISRestoreIndices(isn,&cols)); 1503 PetscFunctionReturn(0); 1504 } 1505 1506 /*@ 1507 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1508 values into a matrix 1509 1510 Not Collective 1511 1512 Input Parameters: 1513 + mat - the matrix 1514 . row - the (block) row to set 1515 - v - a logically two-dimensional array of values 1516 1517 Notes: 1518 By the values, v, are column-oriented (for the block version) and sorted 1519 1520 All the nonzeros in the row must be provided 1521 1522 The matrix must have previously had its column indices set 1523 1524 The row must belong to this process 1525 1526 Level: intermediate 1527 1528 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1529 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()`, `MatSetValuesRow()`, `MatSetLocalToGlobalMapping()` 1530 @*/ 1531 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1532 { 1533 PetscInt globalrow; 1534 1535 PetscFunctionBegin; 1536 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1537 PetscValidType(mat,1); 1538 PetscValidScalarPointer(v,3); 1539 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow)); 1540 PetscCall(MatSetValuesRow(mat,globalrow,v)); 1541 PetscFunctionReturn(0); 1542 } 1543 1544 /*@ 1545 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1546 values into a matrix 1547 1548 Not Collective 1549 1550 Input Parameters: 1551 + mat - the matrix 1552 . row - the (block) row to set 1553 - v - a logically two-dimensional (column major) array of values for block matrices with blocksize larger than one, otherwise a one dimensional array of values 1554 1555 Notes: 1556 The values, v, are column-oriented for the block version. 1557 1558 All the nonzeros in the row must be provided 1559 1560 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1561 1562 The row must belong to this process 1563 1564 Level: advanced 1565 1566 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 1567 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 1568 @*/ 1569 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1570 { 1571 PetscFunctionBeginHot; 1572 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1573 PetscValidType(mat,1); 1574 MatCheckPreallocated(mat,1); 1575 PetscValidScalarPointer(v,3); 1576 PetscCheck(mat->insertmode != ADD_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1577 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1578 mat->insertmode = INSERT_VALUES; 1579 1580 if (mat->assembled) { 1581 mat->was_assembled = PETSC_TRUE; 1582 mat->assembled = PETSC_FALSE; 1583 } 1584 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1585 PetscCheck(mat->ops->setvaluesrow,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1586 PetscCall((*mat->ops->setvaluesrow)(mat,row,v)); 1587 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1588 PetscFunctionReturn(0); 1589 } 1590 1591 /*@ 1592 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1593 Using structured grid indexing 1594 1595 Not Collective 1596 1597 Input Parameters: 1598 + mat - the matrix 1599 . m - number of rows being entered 1600 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1601 . n - number of columns being entered 1602 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1603 . v - a logically two-dimensional array of values 1604 - addv - either ADD_VALUES or INSERT_VALUES, where 1605 ADD_VALUES adds values to any existing entries, and 1606 INSERT_VALUES replaces existing entries with new values 1607 1608 Notes: 1609 By default the values, v, are row-oriented. See MatSetOption() for other options. 1610 1611 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1612 options cannot be mixed without intervening calls to the assembly 1613 routines. 1614 1615 The grid coordinates are across the entire grid, not just the local portion 1616 1617 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1618 as well as in C. 1619 1620 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1621 1622 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1623 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1624 1625 The columns and rows in the stencil passed in MUST be contained within the 1626 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1627 if you create a DMDA with an overlap of one grid level and on a particular process its first 1628 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1629 first i index you can use in your column and row indices in MatSetStencil() is 5. 1630 1631 In Fortran idxm and idxn should be declared as 1632 $ MatStencil idxm(4,m),idxn(4,n) 1633 and the values inserted using 1634 $ idxm(MatStencil_i,1) = i 1635 $ idxm(MatStencil_j,1) = j 1636 $ idxm(MatStencil_k,1) = k 1637 $ idxm(MatStencil_c,1) = c 1638 etc 1639 1640 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1641 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1642 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1643 DM_BOUNDARY_PERIODIC boundary type. 1644 1645 For indices that don't mean anything for your case (like the k index when working in 2d) or the c index when you have 1646 a single value per point) you can skip filling those indices. 1647 1648 Inspired by the structured grid interface to the HYPRE package 1649 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1650 1651 Efficiency Alert: 1652 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1653 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1654 1655 Level: beginner 1656 1657 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1658 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil` 1659 @*/ 1660 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1661 { 1662 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1663 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1664 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1665 1666 PetscFunctionBegin; 1667 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1668 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1669 PetscValidType(mat,1); 1670 PetscValidPointer(idxm,3); 1671 PetscValidPointer(idxn,5); 1672 1673 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1674 jdxm = buf; jdxn = buf+m; 1675 } else { 1676 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1677 jdxm = bufm; jdxn = bufn; 1678 } 1679 for (i=0; i<m; i++) { 1680 for (j=0; j<3-sdim; j++) dxm++; 1681 tmp = *dxm++ - starts[0]; 1682 for (j=0; j<dim-1; j++) { 1683 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1684 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1685 } 1686 if (mat->stencil.noc) dxm++; 1687 jdxm[i] = tmp; 1688 } 1689 for (i=0; i<n; i++) { 1690 for (j=0; j<3-sdim; j++) dxn++; 1691 tmp = *dxn++ - starts[0]; 1692 for (j=0; j<dim-1; j++) { 1693 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1694 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1695 } 1696 if (mat->stencil.noc) dxn++; 1697 jdxn[i] = tmp; 1698 } 1699 PetscCall(MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv)); 1700 PetscCall(PetscFree2(bufm,bufn)); 1701 PetscFunctionReturn(0); 1702 } 1703 1704 /*@ 1705 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1706 Using structured grid indexing 1707 1708 Not Collective 1709 1710 Input Parameters: 1711 + mat - the matrix 1712 . m - number of rows being entered 1713 . idxm - grid coordinates for matrix rows being entered 1714 . n - number of columns being entered 1715 . idxn - grid coordinates for matrix columns being entered 1716 . v - a logically two-dimensional array of values 1717 - addv - either ADD_VALUES or INSERT_VALUES, where 1718 ADD_VALUES adds values to any existing entries, and 1719 INSERT_VALUES replaces existing entries with new values 1720 1721 Notes: 1722 By default the values, v, are row-oriented and unsorted. 1723 See MatSetOption() for other options. 1724 1725 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1726 options cannot be mixed without intervening calls to the assembly 1727 routines. 1728 1729 The grid coordinates are across the entire grid, not just the local portion 1730 1731 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1732 as well as in C. 1733 1734 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1735 1736 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1737 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1738 1739 The columns and rows in the stencil passed in MUST be contained within the 1740 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1741 if you create a DMDA with an overlap of one grid level and on a particular process its first 1742 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1743 first i index you can use in your column and row indices in MatSetStencil() is 5. 1744 1745 In Fortran idxm and idxn should be declared as 1746 $ MatStencil idxm(4,m),idxn(4,n) 1747 and the values inserted using 1748 $ idxm(MatStencil_i,1) = i 1749 $ idxm(MatStencil_j,1) = j 1750 $ idxm(MatStencil_k,1) = k 1751 etc 1752 1753 Negative indices may be passed in idxm and idxn, these rows and columns are 1754 simply ignored. This allows easily inserting element stiffness matrices 1755 with homogeneous Dirchlet boundary conditions that you don't want represented 1756 in the matrix. 1757 1758 Inspired by the structured grid interface to the HYPRE package 1759 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1760 1761 Level: beginner 1762 1763 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1764 `MatSetValues()`, `MatSetValuesStencil()`, `MatSetStencil()`, `DMCreateMatrix()`, `DMDAVecGetArray()`, `MatStencil`, 1765 `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()` 1766 @*/ 1767 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1768 { 1769 PetscInt buf[8192],*bufm=NULL,*bufn=NULL,*jdxm,*jdxn; 1770 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1771 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1772 1773 PetscFunctionBegin; 1774 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1775 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1776 PetscValidType(mat,1); 1777 PetscValidPointer(idxm,3); 1778 PetscValidPointer(idxn,5); 1779 PetscValidScalarPointer(v,6); 1780 1781 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1782 jdxm = buf; jdxn = buf+m; 1783 } else { 1784 PetscCall(PetscMalloc2(m,&bufm,n,&bufn)); 1785 jdxm = bufm; jdxn = bufn; 1786 } 1787 for (i=0; i<m; i++) { 1788 for (j=0; j<3-sdim; j++) dxm++; 1789 tmp = *dxm++ - starts[0]; 1790 for (j=0; j<sdim-1; j++) { 1791 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1792 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1793 } 1794 dxm++; 1795 jdxm[i] = tmp; 1796 } 1797 for (i=0; i<n; i++) { 1798 for (j=0; j<3-sdim; j++) dxn++; 1799 tmp = *dxn++ - starts[0]; 1800 for (j=0; j<sdim-1; j++) { 1801 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1802 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1803 } 1804 dxn++; 1805 jdxn[i] = tmp; 1806 } 1807 PetscCall(MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv)); 1808 PetscCall(PetscFree2(bufm,bufn)); 1809 PetscFunctionReturn(0); 1810 } 1811 1812 /*@ 1813 MatSetStencil - Sets the grid information for setting values into a matrix via 1814 MatSetValuesStencil() 1815 1816 Not Collective 1817 1818 Input Parameters: 1819 + mat - the matrix 1820 . dim - dimension of the grid 1, 2, or 3 1821 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1822 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1823 - dof - number of degrees of freedom per node 1824 1825 Inspired by the structured grid interface to the HYPRE package 1826 (www.llnl.gov/CASC/hyper) 1827 1828 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1829 user. 1830 1831 Level: beginner 1832 1833 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()` 1834 `MatSetValues()`, `MatSetValuesBlockedStencil()`, `MatSetValuesStencil()` 1835 @*/ 1836 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1837 { 1838 PetscFunctionBegin; 1839 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1840 PetscValidIntPointer(dims,3); 1841 PetscValidIntPointer(starts,4); 1842 1843 mat->stencil.dim = dim + (dof > 1); 1844 for (PetscInt i=0; i<dim; i++) { 1845 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1846 mat->stencil.starts[i] = starts[dim-i-1]; 1847 } 1848 mat->stencil.dims[dim] = dof; 1849 mat->stencil.starts[dim] = 0; 1850 mat->stencil.noc = (PetscBool)(dof == 1); 1851 PetscFunctionReturn(0); 1852 } 1853 1854 /*@C 1855 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1856 1857 Not Collective 1858 1859 Input Parameters: 1860 + mat - the matrix 1861 . v - a logically two-dimensional array of values 1862 . m, idxm - the number of block rows and their global block indices 1863 . n, idxn - the number of block columns and their global block indices 1864 - addv - either ADD_VALUES or INSERT_VALUES, where 1865 ADD_VALUES adds values to any existing entries, and 1866 INSERT_VALUES replaces existing entries with new values 1867 1868 Notes: 1869 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1870 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1871 1872 The m and n count the NUMBER of blocks in the row direction and column direction, 1873 NOT the total number of rows/columns; for example, if the block size is 2 and 1874 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1875 The values in idxm would be 1 2; that is the first index for each block divided by 1876 the block size. 1877 1878 Note that you must call MatSetBlockSize() when constructing this matrix (before 1879 preallocating it). 1880 1881 By default the values, v, are row-oriented, so the layout of 1882 v is the same as for MatSetValues(). See MatSetOption() for other options. 1883 1884 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1885 options cannot be mixed without intervening calls to the assembly 1886 routines. 1887 1888 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1889 as well as in C. 1890 1891 Negative indices may be passed in idxm and idxn, these rows and columns are 1892 simply ignored. This allows easily inserting element stiffness matrices 1893 with homogeneous Dirchlet boundary conditions that you don't want represented 1894 in the matrix. 1895 1896 Each time an entry is set within a sparse matrix via MatSetValues(), 1897 internal searching must be done to determine where to place the 1898 data in the matrix storage space. By instead inserting blocks of 1899 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1900 reduced. 1901 1902 Example: 1903 $ Suppose m=n=2 and block size(bs) = 2 The array is 1904 $ 1905 $ 1 2 | 3 4 1906 $ 5 6 | 7 8 1907 $ - - - | - - - 1908 $ 9 10 | 11 12 1909 $ 13 14 | 15 16 1910 $ 1911 $ v[] should be passed in like 1912 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1913 $ 1914 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1915 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1916 1917 Level: intermediate 1918 1919 .seealso: `MatSetBlockSize()`, `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesBlockedLocal()` 1920 @*/ 1921 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1922 { 1923 PetscFunctionBeginHot; 1924 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1925 PetscValidType(mat,1); 1926 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1927 PetscValidIntPointer(idxm,3); 1928 PetscValidIntPointer(idxn,5); 1929 MatCheckPreallocated(mat,1); 1930 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 1931 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1932 if (PetscDefined(USE_DEBUG)) { 1933 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1934 PetscCheck(mat->ops->setvaluesblocked || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1935 } 1936 if (PetscDefined(USE_DEBUG)) { 1937 PetscInt rbs,cbs,M,N,i; 1938 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 1939 PetscCall(MatGetSize(mat,&M,&N)); 1940 for (i=0; i<m; i++) PetscCheck(idxm[i]*rbs < M,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row block index %" PetscInt_FMT " (index %" PetscInt_FMT ") greater than row length %" PetscInt_FMT,i,idxm[i],M); 1941 for (i=0; i<n; i++) PetscCheck(idxn[i]*cbs < N,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column block index %" PetscInt_FMT " (index %" PetscInt_FMT ") great than column length %" PetscInt_FMT,i,idxn[i],N); 1942 } 1943 if (mat->assembled) { 1944 mat->was_assembled = PETSC_TRUE; 1945 mat->assembled = PETSC_FALSE; 1946 } 1947 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 1948 if (mat->ops->setvaluesblocked) { 1949 PetscCall((*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv)); 1950 } else { 1951 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*iidxm,*iidxn; 1952 PetscInt i,j,bs,cbs; 1953 1954 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 1955 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1956 iidxm = buf; 1957 iidxn = buf + m*bs; 1958 } else { 1959 PetscCall(PetscMalloc2(m*bs,&bufr,n*cbs,&bufc)); 1960 iidxm = bufr; 1961 iidxn = bufc; 1962 } 1963 for (i=0; i<m; i++) { 1964 for (j=0; j<bs; j++) { 1965 iidxm[i*bs+j] = bs*idxm[i] + j; 1966 } 1967 } 1968 if (m != n || bs != cbs || idxm != idxn) { 1969 for (i=0; i<n; i++) { 1970 for (j=0; j<cbs; j++) { 1971 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1972 } 1973 } 1974 } else iidxn = iidxm; 1975 PetscCall(MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv)); 1976 PetscCall(PetscFree2(bufr,bufc)); 1977 } 1978 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 1979 PetscFunctionReturn(0); 1980 } 1981 1982 /*@C 1983 MatGetValues - Gets a block of values from a matrix. 1984 1985 Not Collective; can only return values that are owned by the give process 1986 1987 Input Parameters: 1988 + mat - the matrix 1989 . v - a logically two-dimensional array for storing the values 1990 . m, idxm - the number of rows and their global indices 1991 - n, idxn - the number of columns and their global indices 1992 1993 Notes: 1994 The user must allocate space (m*n PetscScalars) for the values, v. 1995 The values, v, are then returned in a row-oriented format, 1996 analogous to that used by default in MatSetValues(). 1997 1998 MatGetValues() uses 0-based row and column numbers in 1999 Fortran as well as in C. 2000 2001 MatGetValues() requires that the matrix has been assembled 2002 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 2003 MatSetValues() and MatGetValues() CANNOT be made in succession 2004 without intermediate matrix assembly. 2005 2006 Negative row or column indices will be ignored and those locations in v[] will be 2007 left unchanged. 2008 2009 For the standard row-based matrix formats, idxm[] can only contain rows owned by the requesting MPI rank. 2010 That is, rows with global index greater than or equal to rstart and less than rend where rstart and rend are obtainable 2011 from MatGetOwnershipRange(mat,&rstart,&rend). 2012 2013 Level: advanced 2014 2015 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatSetValues()`, `MatGetOwnershipRange()`, `MatGetValuesLocal()`, `MatGetValue()` 2016 @*/ 2017 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 2018 { 2019 PetscFunctionBegin; 2020 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2021 PetscValidType(mat,1); 2022 if (!m || !n) PetscFunctionReturn(0); 2023 PetscValidIntPointer(idxm,3); 2024 PetscValidIntPointer(idxn,5); 2025 PetscValidScalarPointer(v,6); 2026 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2027 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2028 PetscCheck(mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2029 MatCheckPreallocated(mat,1); 2030 2031 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2032 PetscCall((*mat->ops->getvalues)(mat,m,idxm,n,idxn,v)); 2033 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2034 PetscFunctionReturn(0); 2035 } 2036 2037 /*@C 2038 MatGetValuesLocal - retrieves values from certain locations in a matrix using the local numbering of the indices 2039 defined previously by MatSetLocalToGlobalMapping() 2040 2041 Not Collective 2042 2043 Input Parameters: 2044 + mat - the matrix 2045 . nrow, irow - number of rows and their local indices 2046 - ncol, icol - number of columns and their local indices 2047 2048 Output Parameter: 2049 . y - a logically two-dimensional array of values 2050 2051 Notes: 2052 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine. 2053 2054 This routine can only return values that are owned by the requesting MPI rank. That is, for standard matrix formats, rows that, in the global numbering, 2055 are greater than or equal to rstart and less than rend where rstart and rend are obtainable from MatGetOwnershipRange(mat,&rstart,&rend). One can 2056 determine if the resulting global row associated with the local row r is owned by the requesting MPI rank by applying the ISLocalToGlobalMapping set 2057 with MatSetLocalToGlobalMapping(). 2058 2059 Developer Notes: 2060 This is labelled with C so does not automatically generate Fortran stubs and interfaces 2061 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2062 2063 Level: advanced 2064 2065 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2066 `MatSetValuesLocal()`, `MatGetValues()` 2067 @*/ 2068 PetscErrorCode MatGetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],PetscScalar y[]) 2069 { 2070 PetscFunctionBeginHot; 2071 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2072 PetscValidType(mat,1); 2073 MatCheckPreallocated(mat,1); 2074 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to retrieve */ 2075 PetscValidIntPointer(irow,3); 2076 PetscValidIntPointer(icol,5); 2077 if (PetscDefined(USE_DEBUG)) { 2078 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2079 PetscCheck(mat->ops->getvalueslocal || mat->ops->getvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2080 } 2081 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2082 PetscCall(PetscLogEventBegin(MAT_GetValues,mat,0,0,0)); 2083 if (mat->ops->getvalueslocal) { 2084 PetscCall((*mat->ops->getvalueslocal)(mat,nrow,irow,ncol,icol,y)); 2085 } else { 2086 PetscInt buf[8192],*bufr=NULL,*bufc=NULL,*irowm,*icolm; 2087 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2088 irowm = buf; icolm = buf+nrow; 2089 } else { 2090 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2091 irowm = bufr; icolm = bufc; 2092 } 2093 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global row mapping (See MatSetLocalToGlobalMapping())."); 2094 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MatGetValuesLocal() cannot proceed without local-to-global column mapping (See MatSetLocalToGlobalMapping())."); 2095 PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm)); 2096 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm)); 2097 PetscCall(MatGetValues(mat,nrow,irowm,ncol,icolm,y)); 2098 PetscCall(PetscFree2(bufr,bufc)); 2099 } 2100 PetscCall(PetscLogEventEnd(MAT_GetValues,mat,0,0,0)); 2101 PetscFunctionReturn(0); 2102 } 2103 2104 /*@ 2105 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 2106 the same size. Currently, this can only be called once and creates the given matrix. 2107 2108 Not Collective 2109 2110 Input Parameters: 2111 + mat - the matrix 2112 . nb - the number of blocks 2113 . bs - the number of rows (and columns) in each block 2114 . rows - a concatenation of the rows for each block 2115 - v - a concatenation of logically two-dimensional arrays of values 2116 2117 Notes: 2118 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 2119 2120 Level: advanced 2121 2122 .seealso: `MatSetOption()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValuesBlocked()`, `MatSetValuesLocal()`, 2123 `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `MatSetValues()` 2124 @*/ 2125 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 2126 { 2127 PetscFunctionBegin; 2128 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2129 PetscValidType(mat,1); 2130 PetscValidIntPointer(rows,4); 2131 PetscValidScalarPointer(v,5); 2132 PetscAssert(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2133 2134 PetscCall(PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0)); 2135 if (mat->ops->setvaluesbatch) { 2136 PetscCall((*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v)); 2137 } else { 2138 for (PetscInt b = 0; b < nb; ++b) PetscCall(MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES)); 2139 } 2140 PetscCall(PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0)); 2141 PetscFunctionReturn(0); 2142 } 2143 2144 /*@ 2145 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2146 the routine MatSetValuesLocal() to allow users to insert matrix entries 2147 using a local (per-processor) numbering. 2148 2149 Not Collective 2150 2151 Input Parameters: 2152 + x - the matrix 2153 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2154 - cmapping - column mapping 2155 2156 Level: intermediate 2157 2158 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetValuesLocal()`, `MatGetValuesLocal()` 2159 @*/ 2160 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2161 { 2162 PetscFunctionBegin; 2163 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2164 PetscValidType(x,1); 2165 if (rmapping) PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2166 if (cmapping) PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2167 if (x->ops->setlocaltoglobalmapping) { 2168 PetscCall((*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping)); 2169 } else { 2170 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping)); 2171 PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping)); 2172 } 2173 PetscFunctionReturn(0); 2174 } 2175 2176 /*@ 2177 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2178 2179 Not Collective 2180 2181 Input Parameter: 2182 . A - the matrix 2183 2184 Output Parameters: 2185 + rmapping - row mapping 2186 - cmapping - column mapping 2187 2188 Level: advanced 2189 2190 .seealso: `MatSetValuesLocal()` 2191 @*/ 2192 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2193 { 2194 PetscFunctionBegin; 2195 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2196 PetscValidType(A,1); 2197 if (rmapping) { 2198 PetscValidPointer(rmapping,2); 2199 *rmapping = A->rmap->mapping; 2200 } 2201 if (cmapping) { 2202 PetscValidPointer(cmapping,3); 2203 *cmapping = A->cmap->mapping; 2204 } 2205 PetscFunctionReturn(0); 2206 } 2207 2208 /*@ 2209 MatSetLayouts - Sets the PetscLayout objects for rows and columns of a matrix 2210 2211 Logically Collective on A 2212 2213 Input Parameters: 2214 + A - the matrix 2215 . rmap - row layout 2216 - cmap - column layout 2217 2218 Level: advanced 2219 2220 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatGetLayouts()` 2221 @*/ 2222 PetscErrorCode MatSetLayouts(Mat A,PetscLayout rmap,PetscLayout cmap) 2223 { 2224 PetscFunctionBegin; 2225 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2226 PetscCall(PetscLayoutReference(rmap,&A->rmap)); 2227 PetscCall(PetscLayoutReference(cmap,&A->cmap)); 2228 PetscFunctionReturn(0); 2229 } 2230 2231 /*@ 2232 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2233 2234 Not Collective 2235 2236 Input Parameter: 2237 . A - the matrix 2238 2239 Output Parameters: 2240 + rmap - row layout 2241 - cmap - column layout 2242 2243 Level: advanced 2244 2245 .seealso: `MatCreateVecs()`, `MatGetLocalToGlobalMapping()`, `MatSetLayouts()` 2246 @*/ 2247 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2248 { 2249 PetscFunctionBegin; 2250 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2251 PetscValidType(A,1); 2252 if (rmap) { 2253 PetscValidPointer(rmap,2); 2254 *rmap = A->rmap; 2255 } 2256 if (cmap) { 2257 PetscValidPointer(cmap,3); 2258 *cmap = A->cmap; 2259 } 2260 PetscFunctionReturn(0); 2261 } 2262 2263 /*@C 2264 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2265 using a local numbering of the nodes. 2266 2267 Not Collective 2268 2269 Input Parameters: 2270 + mat - the matrix 2271 . nrow, irow - number of rows and their local indices 2272 . ncol, icol - number of columns and their local indices 2273 . y - a logically two-dimensional array of values 2274 - addv - either INSERT_VALUES or ADD_VALUES, where 2275 ADD_VALUES adds values to any existing entries, and 2276 INSERT_VALUES replaces existing entries with new values 2277 2278 Notes: 2279 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2280 MatSetUp() before using this routine 2281 2282 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2283 2284 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2285 options cannot be mixed without intervening calls to the assembly 2286 routines. 2287 2288 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2289 MUST be called after all calls to MatSetValuesLocal() have been completed. 2290 2291 Level: intermediate 2292 2293 Developer Notes: 2294 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2295 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2296 2297 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `MatSetValues()`, `MatSetLocalToGlobalMapping()`, 2298 `MatSetValueLocal()`, `MatGetValuesLocal()` 2299 @*/ 2300 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2301 { 2302 PetscFunctionBeginHot; 2303 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2304 PetscValidType(mat,1); 2305 MatCheckPreallocated(mat,1); 2306 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2307 PetscValidIntPointer(irow,3); 2308 PetscValidIntPointer(icol,5); 2309 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2310 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2311 if (PetscDefined(USE_DEBUG)) { 2312 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2313 PetscCheck(mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2314 } 2315 2316 if (mat->assembled) { 2317 mat->was_assembled = PETSC_TRUE; 2318 mat->assembled = PETSC_FALSE; 2319 } 2320 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2321 if (mat->ops->setvalueslocal) { 2322 PetscCall((*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv)); 2323 } else { 2324 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2325 const PetscInt *irowm,*icolm; 2326 2327 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2328 bufr = buf; 2329 bufc = buf + nrow; 2330 irowm = bufr; 2331 icolm = bufc; 2332 } else { 2333 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2334 irowm = bufr; 2335 icolm = bufc; 2336 } 2337 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,bufr)); 2338 else irowm = irow; 2339 if (mat->cmap->mapping) { 2340 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2341 PetscCall(ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,bufc)); 2342 } else icolm = irowm; 2343 } else icolm = icol; 2344 PetscCall(MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv)); 2345 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2346 } 2347 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2348 PetscFunctionReturn(0); 2349 } 2350 2351 /*@C 2352 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2353 using a local ordering of the nodes a block at a time. 2354 2355 Not Collective 2356 2357 Input Parameters: 2358 + x - the matrix 2359 . nrow, irow - number of rows and their local indices 2360 . ncol, icol - number of columns and their local indices 2361 . y - a logically two-dimensional array of values 2362 - addv - either INSERT_VALUES or ADD_VALUES, where 2363 ADD_VALUES adds values to any existing entries, and 2364 INSERT_VALUES replaces existing entries with new values 2365 2366 Notes: 2367 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2368 MatSetUp() before using this routine 2369 2370 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2371 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2372 2373 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2374 options cannot be mixed without intervening calls to the assembly 2375 routines. 2376 2377 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2378 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2379 2380 Level: intermediate 2381 2382 Developer Notes: 2383 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2384 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2385 2386 .seealso: `MatSetBlockSize()`, `MatSetLocalToGlobalMapping()`, `MatAssemblyBegin()`, `MatAssemblyEnd()`, 2387 `MatSetValuesLocal()`, `MatSetValuesBlocked()` 2388 @*/ 2389 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2390 { 2391 PetscFunctionBeginHot; 2392 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2393 PetscValidType(mat,1); 2394 MatCheckPreallocated(mat,1); 2395 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2396 PetscValidIntPointer(irow,3); 2397 PetscValidIntPointer(icol,5); 2398 if (mat->insertmode == NOT_SET_VALUES) mat->insertmode = addv; 2399 else PetscCheck(mat->insertmode == addv,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2400 if (PetscDefined(USE_DEBUG)) { 2401 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2402 PetscCheck(mat->ops->setvaluesblockedlocal || mat->ops->setvaluesblocked || mat->ops->setvalueslocal || mat->ops->setvalues,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2403 } 2404 2405 if (mat->assembled) { 2406 mat->was_assembled = PETSC_TRUE; 2407 mat->assembled = PETSC_FALSE; 2408 } 2409 if (PetscUnlikelyDebug(mat->rmap->mapping)) { /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2410 PetscInt irbs, rbs; 2411 PetscCall(MatGetBlockSizes(mat, &rbs, NULL)); 2412 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs)); 2413 PetscCheck(rbs == irbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %" PetscInt_FMT ", row l2g map %" PetscInt_FMT,rbs,irbs); 2414 } 2415 if (PetscUnlikelyDebug(mat->cmap->mapping)) { 2416 PetscInt icbs, cbs; 2417 PetscCall(MatGetBlockSizes(mat,NULL,&cbs)); 2418 PetscCall(ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs)); 2419 PetscCheck(cbs == icbs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %" PetscInt_FMT ", col l2g map %" PetscInt_FMT,cbs,icbs); 2420 } 2421 PetscCall(PetscLogEventBegin(MAT_SetValues,mat,0,0,0)); 2422 if (mat->ops->setvaluesblockedlocal) { 2423 PetscCall((*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv)); 2424 } else { 2425 PetscInt buf[8192],*bufr=NULL,*bufc=NULL; 2426 const PetscInt *irowm,*icolm; 2427 2428 if ((!mat->rmap->mapping && !mat->cmap->mapping) || (nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2429 bufr = buf; 2430 bufc = buf + nrow; 2431 irowm = bufr; 2432 icolm = bufc; 2433 } else { 2434 PetscCall(PetscMalloc2(nrow,&bufr,ncol,&bufc)); 2435 irowm = bufr; 2436 icolm = bufc; 2437 } 2438 if (mat->rmap->mapping) PetscCall(ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,bufr)); 2439 else irowm = irow; 2440 if (mat->cmap->mapping) { 2441 if (mat->cmap->mapping != mat->rmap->mapping || ncol != nrow || icol != irow) { 2442 PetscCall(ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,bufc)); 2443 } else icolm = irowm; 2444 } else icolm = icol; 2445 PetscCall(MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv)); 2446 if (bufr != buf) PetscCall(PetscFree2(bufr,bufc)); 2447 } 2448 PetscCall(PetscLogEventEnd(MAT_SetValues,mat,0,0,0)); 2449 PetscFunctionReturn(0); 2450 } 2451 2452 /*@ 2453 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2454 2455 Collective on Mat 2456 2457 Input Parameters: 2458 + mat - the matrix 2459 - x - the vector to be multiplied 2460 2461 Output Parameters: 2462 . y - the result 2463 2464 Notes: 2465 The vectors x and y cannot be the same. I.e., one cannot 2466 call MatMult(A,y,y). 2467 2468 Level: developer 2469 2470 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2471 @*/ 2472 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2473 { 2474 PetscFunctionBegin; 2475 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2476 PetscValidType(mat,1); 2477 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2478 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2479 2480 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2481 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2482 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2483 MatCheckPreallocated(mat,1); 2484 2485 PetscCheck(mat->ops->multdiagonalblock,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2486 PetscCall((*mat->ops->multdiagonalblock)(mat,x,y)); 2487 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2488 PetscFunctionReturn(0); 2489 } 2490 2491 /* --------------------------------------------------------*/ 2492 /*@ 2493 MatMult - Computes the matrix-vector product, y = Ax. 2494 2495 Neighbor-wise Collective on Mat 2496 2497 Input Parameters: 2498 + mat - the matrix 2499 - x - the vector to be multiplied 2500 2501 Output Parameters: 2502 . y - the result 2503 2504 Notes: 2505 The vectors x and y cannot be the same. I.e., one cannot 2506 call MatMult(A,y,y). 2507 2508 Level: beginner 2509 2510 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 2511 @*/ 2512 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2513 { 2514 PetscFunctionBegin; 2515 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2516 PetscValidType(mat,1); 2517 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2518 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2519 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2520 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2521 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2522 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 2523 PetscCheck(mat->rmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N); 2524 PetscCheck(mat->cmap->n == x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,x->map->n); 2525 PetscCheck(mat->rmap->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,y->map->n); 2526 PetscCall(VecSetErrorIfLocked(y,3)); 2527 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2528 MatCheckPreallocated(mat,1); 2529 2530 PetscCall(VecLockReadPush(x)); 2531 PetscCheck(mat->ops->mult,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2532 PetscCall(PetscLogEventBegin(MAT_Mult,mat,x,y,0)); 2533 PetscCall((*mat->ops->mult)(mat,x,y)); 2534 PetscCall(PetscLogEventEnd(MAT_Mult,mat,x,y,0)); 2535 if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE)); 2536 PetscCall(VecLockReadPop(x)); 2537 PetscFunctionReturn(0); 2538 } 2539 2540 /*@ 2541 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2542 2543 Neighbor-wise Collective on Mat 2544 2545 Input Parameters: 2546 + mat - the matrix 2547 - x - the vector to be multiplied 2548 2549 Output Parameters: 2550 . y - the result 2551 2552 Notes: 2553 The vectors x and y cannot be the same. I.e., one cannot 2554 call MatMultTranspose(A,y,y). 2555 2556 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2557 use MatMultHermitianTranspose() 2558 2559 Level: beginner 2560 2561 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultTransposeAdd()`, `MatMultHermitianTranspose()`, `MatTranspose()` 2562 @*/ 2563 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2564 { 2565 PetscErrorCode (*op)(Mat,Vec,Vec) = NULL; 2566 2567 PetscFunctionBegin; 2568 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2569 PetscValidType(mat,1); 2570 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2571 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2572 2573 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2574 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2575 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2576 PetscCheck(mat->cmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 2577 PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 2578 PetscCheck(mat->cmap->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,y->map->n); 2579 PetscCheck(mat->rmap->n == x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,x->map->n); 2580 if (mat->erroriffailure) PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2581 MatCheckPreallocated(mat,1); 2582 2583 if (!mat->ops->multtranspose) { 2584 if (mat->symmetric && mat->ops->mult) op = mat->ops->mult; 2585 PetscCheck(op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply transpose defined or is symmetric and does not have a multiply defined",((PetscObject)mat)->type_name); 2586 } else op = mat->ops->multtranspose; 2587 PetscCall(PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0)); 2588 PetscCall(VecLockReadPush(x)); 2589 PetscCall((*op)(mat,x,y)); 2590 PetscCall(VecLockReadPop(x)); 2591 PetscCall(PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0)); 2592 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2593 if (mat->erroriffailure) PetscCall(VecValidValues(y,3,PETSC_FALSE)); 2594 PetscFunctionReturn(0); 2595 } 2596 2597 /*@ 2598 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2599 2600 Neighbor-wise Collective on Mat 2601 2602 Input Parameters: 2603 + mat - the matrix 2604 - x - the vector to be multilplied 2605 2606 Output Parameters: 2607 . y - the result 2608 2609 Notes: 2610 The vectors x and y cannot be the same. I.e., one cannot 2611 call MatMultHermitianTranspose(A,y,y). 2612 2613 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2614 2615 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2616 2617 Level: beginner 2618 2619 .seealso: `MatMult()`, `MatMultAdd()`, `MatMultHermitianTransposeAdd()`, `MatMultTranspose()` 2620 @*/ 2621 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2622 { 2623 PetscFunctionBegin; 2624 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2625 PetscValidType(mat,1); 2626 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2627 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2628 2629 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2630 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2631 PetscCheck(x != y,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2632 PetscCheck(mat->cmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 2633 PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 2634 PetscCheck(mat->cmap->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->n,y->map->n); 2635 PetscCheck(mat->rmap->n == x->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,x->map->n); 2636 MatCheckPreallocated(mat,1); 2637 2638 PetscCall(PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0)); 2639 #if defined(PETSC_USE_COMPLEX) 2640 if (mat->ops->multhermitiantranspose || (mat->hermitian && mat->ops->mult)) { 2641 PetscCall(VecLockReadPush(x)); 2642 if (mat->ops->multhermitiantranspose) { 2643 PetscCall((*mat->ops->multhermitiantranspose)(mat,x,y)); 2644 } else { 2645 PetscCall((*mat->ops->mult)(mat,x,y)); 2646 } 2647 PetscCall(VecLockReadPop(x)); 2648 } else { 2649 Vec w; 2650 PetscCall(VecDuplicate(x,&w)); 2651 PetscCall(VecCopy(x,w)); 2652 PetscCall(VecConjugate(w)); 2653 PetscCall(MatMultTranspose(mat,w,y)); 2654 PetscCall(VecDestroy(&w)); 2655 PetscCall(VecConjugate(y)); 2656 } 2657 PetscCall(PetscObjectStateIncrease((PetscObject)y)); 2658 #else 2659 PetscCall(MatMultTranspose(mat,x,y)); 2660 #endif 2661 PetscCall(PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0)); 2662 PetscFunctionReturn(0); 2663 } 2664 2665 /*@ 2666 MatMultAdd - Computes v3 = v2 + A * v1. 2667 2668 Neighbor-wise Collective on Mat 2669 2670 Input Parameters: 2671 + mat - the matrix 2672 - v1, v2 - the vectors 2673 2674 Output Parameters: 2675 . v3 - the result 2676 2677 Notes: 2678 The vectors v1 and v3 cannot be the same. I.e., one cannot 2679 call MatMultAdd(A,v1,v2,v1). 2680 2681 Level: beginner 2682 2683 .seealso: `MatMultTranspose()`, `MatMult()`, `MatMultTransposeAdd()` 2684 @*/ 2685 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2686 { 2687 PetscFunctionBegin; 2688 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2689 PetscValidType(mat,1); 2690 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2691 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2692 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2693 2694 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2695 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2696 PetscCheck(mat->cmap->N == v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v1->map->N); 2697 /* PetscCheck(mat->rmap->N == v2->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v2->map->N); 2698 PetscCheck(mat->rmap->N == v3->map->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v3->map->N); */ 2699 PetscCheck(mat->rmap->n == v3->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,v3->map->n); 2700 PetscCheck(mat->rmap->n == v2->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,v2->map->n); 2701 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2702 MatCheckPreallocated(mat,1); 2703 2704 PetscCheck(mat->ops->multadd,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type %s",((PetscObject)mat)->type_name); 2705 PetscCall(PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3)); 2706 PetscCall(VecLockReadPush(v1)); 2707 PetscCall((*mat->ops->multadd)(mat,v1,v2,v3)); 2708 PetscCall(VecLockReadPop(v1)); 2709 PetscCall(PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3)); 2710 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2711 PetscFunctionReturn(0); 2712 } 2713 2714 /*@ 2715 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2716 2717 Neighbor-wise Collective on Mat 2718 2719 Input Parameters: 2720 + mat - the matrix 2721 - v1, v2 - the vectors 2722 2723 Output Parameters: 2724 . v3 - the result 2725 2726 Notes: 2727 The vectors v1 and v3 cannot be the same. I.e., one cannot 2728 call MatMultTransposeAdd(A,v1,v2,v1). 2729 2730 Level: beginner 2731 2732 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2733 @*/ 2734 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2735 { 2736 PetscErrorCode (*op)(Mat,Vec,Vec,Vec) = (!mat->ops->multtransposeadd && mat->symmetric) ? mat->ops->multadd : mat->ops->multtransposeadd; 2737 2738 PetscFunctionBegin; 2739 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2740 PetscValidType(mat,1); 2741 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2742 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2743 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2744 2745 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2746 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2747 PetscCheck(mat->rmap->N == v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v1->map->N); 2748 PetscCheck(mat->cmap->N == v2->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v2->map->N); 2749 PetscCheck(mat->cmap->N == v3->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v3->map->N); 2750 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2751 PetscCheck(op,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2752 MatCheckPreallocated(mat,1); 2753 2754 PetscCall(PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2755 PetscCall(VecLockReadPush(v1)); 2756 PetscCall((*op)(mat,v1,v2,v3)); 2757 PetscCall(VecLockReadPop(v1)); 2758 PetscCall(PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3)); 2759 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2760 PetscFunctionReturn(0); 2761 } 2762 2763 /*@ 2764 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2765 2766 Neighbor-wise Collective on Mat 2767 2768 Input Parameters: 2769 + mat - the matrix 2770 - v1, v2 - the vectors 2771 2772 Output Parameters: 2773 . v3 - the result 2774 2775 Notes: 2776 The vectors v1 and v3 cannot be the same. I.e., one cannot 2777 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2778 2779 Level: beginner 2780 2781 .seealso: `MatMultHermitianTranspose()`, `MatMultTranspose()`, `MatMultAdd()`, `MatMult()` 2782 @*/ 2783 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2784 { 2785 PetscFunctionBegin; 2786 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2787 PetscValidType(mat,1); 2788 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2789 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2790 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2791 2792 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2793 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2794 PetscCheck(v1 != v3,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2795 PetscCheck(mat->rmap->N == v1->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,v1->map->N); 2796 PetscCheck(mat->cmap->N == v2->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v2->map->N); 2797 PetscCheck(mat->cmap->N == v3->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,v3->map->N); 2798 MatCheckPreallocated(mat,1); 2799 2800 PetscCall(PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2801 PetscCall(VecLockReadPush(v1)); 2802 if (mat->ops->multhermitiantransposeadd) { 2803 PetscCall((*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3)); 2804 } else { 2805 Vec w,z; 2806 PetscCall(VecDuplicate(v1,&w)); 2807 PetscCall(VecCopy(v1,w)); 2808 PetscCall(VecConjugate(w)); 2809 PetscCall(VecDuplicate(v3,&z)); 2810 PetscCall(MatMultTranspose(mat,w,z)); 2811 PetscCall(VecDestroy(&w)); 2812 PetscCall(VecConjugate(z)); 2813 if (v2 != v3) { 2814 PetscCall(VecWAXPY(v3,1.0,v2,z)); 2815 } else { 2816 PetscCall(VecAXPY(v3,1.0,z)); 2817 } 2818 PetscCall(VecDestroy(&z)); 2819 } 2820 PetscCall(VecLockReadPop(v1)); 2821 PetscCall(PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3)); 2822 PetscCall(PetscObjectStateIncrease((PetscObject)v3)); 2823 PetscFunctionReturn(0); 2824 } 2825 2826 /*@C 2827 MatGetFactorType - gets the type of factorization it is 2828 2829 Not Collective 2830 2831 Input Parameters: 2832 . mat - the matrix 2833 2834 Output Parameters: 2835 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2836 2837 Level: intermediate 2838 2839 .seealso: `MatFactorType`, `MatGetFactor()`, `MatSetFactorType()` 2840 @*/ 2841 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2842 { 2843 PetscFunctionBegin; 2844 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2845 PetscValidType(mat,1); 2846 PetscValidPointer(t,2); 2847 *t = mat->factortype; 2848 PetscFunctionReturn(0); 2849 } 2850 2851 /*@C 2852 MatSetFactorType - sets the type of factorization it is 2853 2854 Logically Collective on Mat 2855 2856 Input Parameters: 2857 + mat - the matrix 2858 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2859 2860 Level: intermediate 2861 2862 .seealso: `MatFactorType`, `MatGetFactor()`, `MatGetFactorType()` 2863 @*/ 2864 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2865 { 2866 PetscFunctionBegin; 2867 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2868 PetscValidType(mat,1); 2869 mat->factortype = t; 2870 PetscFunctionReturn(0); 2871 } 2872 2873 /* ------------------------------------------------------------*/ 2874 /*@C 2875 MatGetInfo - Returns information about matrix storage (number of 2876 nonzeros, memory, etc.). 2877 2878 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2879 2880 Input Parameter: 2881 . mat - the matrix 2882 2883 Output Parameters: 2884 + flag - flag indicating the type of parameters to be returned 2885 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2886 MAT_GLOBAL_SUM - sum over all processors) 2887 - info - matrix information context 2888 2889 Notes: 2890 The MatInfo context contains a variety of matrix data, including 2891 number of nonzeros allocated and used, number of mallocs during 2892 matrix assembly, etc. Additional information for factored matrices 2893 is provided (such as the fill ratio, number of mallocs during 2894 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2895 when using the runtime options 2896 $ -info -mat_view ::ascii_info 2897 2898 Example for C/C++ Users: 2899 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2900 data within the MatInfo context. For example, 2901 .vb 2902 MatInfo info; 2903 Mat A; 2904 double mal, nz_a, nz_u; 2905 2906 MatGetInfo(A,MAT_LOCAL,&info); 2907 mal = info.mallocs; 2908 nz_a = info.nz_allocated; 2909 .ve 2910 2911 Example for Fortran Users: 2912 Fortran users should declare info as a double precision 2913 array of dimension MAT_INFO_SIZE, and then extract the parameters 2914 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2915 a complete list of parameter names. 2916 .vb 2917 double precision info(MAT_INFO_SIZE) 2918 double precision mal, nz_a 2919 Mat A 2920 integer ierr 2921 2922 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2923 mal = info(MAT_INFO_MALLOCS) 2924 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2925 .ve 2926 2927 Level: intermediate 2928 2929 Developer Note: fortran interface is not autogenerated as the f90 2930 interface definition cannot be generated correctly [due to MatInfo] 2931 2932 .seealso: `MatStashGetInfo()` 2933 2934 @*/ 2935 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2936 { 2937 PetscFunctionBegin; 2938 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2939 PetscValidType(mat,1); 2940 PetscValidPointer(info,3); 2941 PetscCheck(mat->ops->getinfo,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2942 MatCheckPreallocated(mat,1); 2943 PetscCall((*mat->ops->getinfo)(mat,flag,info)); 2944 PetscFunctionReturn(0); 2945 } 2946 2947 /* 2948 This is used by external packages where it is not easy to get the info from the actual 2949 matrix factorization. 2950 */ 2951 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2952 { 2953 PetscFunctionBegin; 2954 PetscCall(PetscMemzero(info,sizeof(MatInfo))); 2955 PetscFunctionReturn(0); 2956 } 2957 2958 /* ----------------------------------------------------------*/ 2959 2960 /*@C 2961 MatLUFactor - Performs in-place LU factorization of matrix. 2962 2963 Collective on Mat 2964 2965 Input Parameters: 2966 + mat - the matrix 2967 . row - row permutation 2968 . col - column permutation 2969 - info - options for factorization, includes 2970 $ fill - expected fill as ratio of original fill. 2971 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2972 $ Run with the option -info to determine an optimal value to use 2973 2974 Notes: 2975 Most users should employ the simplified KSP interface for linear solvers 2976 instead of working directly with matrix algebra routines such as this. 2977 See, e.g., KSPCreate(). 2978 2979 This changes the state of the matrix to a factored matrix; it cannot be used 2980 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2981 2982 Level: developer 2983 2984 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, 2985 `MatGetOrdering()`, `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 2986 2987 Developer Note: fortran interface is not autogenerated as the f90 2988 interface definition cannot be generated correctly [due to MatFactorInfo] 2989 2990 @*/ 2991 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2992 { 2993 MatFactorInfo tinfo; 2994 2995 PetscFunctionBegin; 2996 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2997 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2998 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2999 if (info) PetscValidPointer(info,4); 3000 PetscValidType(mat,1); 3001 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3002 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3003 PetscCheck(mat->ops->lufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3004 MatCheckPreallocated(mat,1); 3005 if (!info) { 3006 PetscCall(MatFactorInfoInitialize(&tinfo)); 3007 info = &tinfo; 3008 } 3009 3010 PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,row,col,0)); 3011 PetscCall((*mat->ops->lufactor)(mat,row,col,info)); 3012 PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,row,col,0)); 3013 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3014 PetscFunctionReturn(0); 3015 } 3016 3017 /*@C 3018 MatILUFactor - Performs in-place ILU factorization of matrix. 3019 3020 Collective on Mat 3021 3022 Input Parameters: 3023 + mat - the matrix 3024 . row - row permutation 3025 . col - column permutation 3026 - info - structure containing 3027 $ levels - number of levels of fill. 3028 $ expected fill - as ratio of original fill. 3029 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 3030 missing diagonal entries) 3031 3032 Notes: 3033 Probably really in-place only when level of fill is zero, otherwise allocates 3034 new space to store factored matrix and deletes previous memory. 3035 3036 Most users should employ the simplified KSP interface for linear solvers 3037 instead of working directly with matrix algebra routines such as this. 3038 See, e.g., KSPCreate(). 3039 3040 Level: developer 3041 3042 .seealso: `MatILUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 3043 3044 Developer Note: fortran interface is not autogenerated as the f90 3045 interface definition cannot be generated correctly [due to MatFactorInfo] 3046 3047 @*/ 3048 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 3049 { 3050 PetscFunctionBegin; 3051 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3052 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3053 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3054 PetscValidPointer(info,4); 3055 PetscValidType(mat,1); 3056 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 3057 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3058 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3059 PetscCheck(mat->ops->ilufactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3060 MatCheckPreallocated(mat,1); 3061 3062 PetscCall(PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0)); 3063 PetscCall((*mat->ops->ilufactor)(mat,row,col,info)); 3064 PetscCall(PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0)); 3065 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3066 PetscFunctionReturn(0); 3067 } 3068 3069 /*@C 3070 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 3071 Call this routine before calling MatLUFactorNumeric(). 3072 3073 Collective on Mat 3074 3075 Input Parameters: 3076 + fact - the factor matrix obtained with MatGetFactor() 3077 . mat - the matrix 3078 . row, col - row and column permutations 3079 - info - options for factorization, includes 3080 $ fill - expected fill as ratio of original fill. 3081 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3082 $ Run with the option -info to determine an optimal value to use 3083 3084 Notes: 3085 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3086 3087 Most users should employ the simplified KSP interface for linear solvers 3088 instead of working directly with matrix algebra routines such as this. 3089 See, e.g., KSPCreate(). 3090 3091 Level: developer 3092 3093 .seealso: `MatLUFactor()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3094 3095 Developer Note: fortran interface is not autogenerated as the f90 3096 interface definition cannot be generated correctly [due to MatFactorInfo] 3097 3098 @*/ 3099 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3100 { 3101 MatFactorInfo tinfo; 3102 3103 PetscFunctionBegin; 3104 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3105 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 3106 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 3107 if (info) PetscValidPointer(info,5); 3108 PetscValidType(mat,2); 3109 PetscValidPointer(fact,1); 3110 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3111 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3112 if (!(fact)->ops->lufactorsymbolic) { 3113 MatSolverType stype; 3114 PetscCall(MatFactorGetSolverType(fact,&stype)); 3115 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,stype); 3116 } 3117 MatCheckPreallocated(mat,2); 3118 if (!info) { 3119 PetscCall(MatFactorInfoInitialize(&tinfo)); 3120 info = &tinfo; 3121 } 3122 3123 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0)); 3124 PetscCall((fact->ops->lufactorsymbolic)(fact,mat,row,col,info)); 3125 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0)); 3126 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3127 PetscFunctionReturn(0); 3128 } 3129 3130 /*@C 3131 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3132 Call this routine after first calling MatLUFactorSymbolic(). 3133 3134 Collective on Mat 3135 3136 Input Parameters: 3137 + fact - the factor matrix obtained with MatGetFactor() 3138 . mat - the matrix 3139 - info - options for factorization 3140 3141 Notes: 3142 See MatLUFactor() for in-place factorization. See 3143 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3144 3145 Most users should employ the simplified KSP interface for linear solvers 3146 instead of working directly with matrix algebra routines such as this. 3147 See, e.g., KSPCreate(). 3148 3149 Level: developer 3150 3151 .seealso: `MatLUFactorSymbolic()`, `MatLUFactor()`, `MatCholeskyFactor()` 3152 3153 Developer Note: fortran interface is not autogenerated as the f90 3154 interface definition cannot be generated correctly [due to MatFactorInfo] 3155 3156 @*/ 3157 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3158 { 3159 MatFactorInfo tinfo; 3160 3161 PetscFunctionBegin; 3162 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3163 PetscValidType(mat,2); 3164 PetscValidPointer(fact,1); 3165 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3166 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3167 PetscCheck(mat->rmap->N == (fact)->rmap->N && mat->cmap->N == (fact)->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3168 3169 PetscCheck((fact)->ops->lufactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3170 MatCheckPreallocated(mat,2); 3171 if (!info) { 3172 PetscCall(MatFactorInfoInitialize(&tinfo)); 3173 info = &tinfo; 3174 } 3175 3176 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0)); 3177 else PetscCall(PetscLogEventBegin(MAT_LUFactor,mat,fact,0,0)); 3178 PetscCall((fact->ops->lufactornumeric)(fact,mat,info)); 3179 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0)); 3180 else PetscCall(PetscLogEventEnd(MAT_LUFactor,mat,fact,0,0)); 3181 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3182 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3183 PetscFunctionReturn(0); 3184 } 3185 3186 /*@C 3187 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3188 symmetric matrix. 3189 3190 Collective on Mat 3191 3192 Input Parameters: 3193 + mat - the matrix 3194 . perm - row and column permutations 3195 - f - expected fill as ratio of original fill 3196 3197 Notes: 3198 See MatLUFactor() for the nonsymmetric case. See also 3199 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3200 3201 Most users should employ the simplified KSP interface for linear solvers 3202 instead of working directly with matrix algebra routines such as this. 3203 See, e.g., KSPCreate(). 3204 3205 Level: developer 3206 3207 .seealso: `MatLUFactor()`, `MatCholeskyFactorSymbolic()`, `MatCholeskyFactorNumeric()` 3208 `MatGetOrdering()` 3209 3210 Developer Note: fortran interface is not autogenerated as the f90 3211 interface definition cannot be generated correctly [due to MatFactorInfo] 3212 3213 @*/ 3214 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3215 { 3216 MatFactorInfo tinfo; 3217 3218 PetscFunctionBegin; 3219 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3220 PetscValidType(mat,1); 3221 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3222 if (info) PetscValidPointer(info,3); 3223 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3224 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3225 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3226 PetscCheck(mat->ops->choleskyfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name); 3227 MatCheckPreallocated(mat,1); 3228 if (!info) { 3229 PetscCall(MatFactorInfoInitialize(&tinfo)); 3230 info = &tinfo; 3231 } 3232 3233 PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0)); 3234 PetscCall((*mat->ops->choleskyfactor)(mat,perm,info)); 3235 PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0)); 3236 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3237 PetscFunctionReturn(0); 3238 } 3239 3240 /*@C 3241 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3242 of a symmetric matrix. 3243 3244 Collective on Mat 3245 3246 Input Parameters: 3247 + fact - the factor matrix obtained with MatGetFactor() 3248 . mat - the matrix 3249 . perm - row and column permutations 3250 - info - options for factorization, includes 3251 $ fill - expected fill as ratio of original fill. 3252 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3253 $ Run with the option -info to determine an optimal value to use 3254 3255 Notes: 3256 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3257 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3258 3259 Most users should employ the simplified KSP interface for linear solvers 3260 instead of working directly with matrix algebra routines such as this. 3261 See, e.g., KSPCreate(). 3262 3263 Level: developer 3264 3265 .seealso: `MatLUFactorSymbolic()`, `MatCholeskyFactor()`, `MatCholeskyFactorNumeric()` 3266 `MatGetOrdering()` 3267 3268 Developer Note: fortran interface is not autogenerated as the f90 3269 interface definition cannot be generated correctly [due to MatFactorInfo] 3270 3271 @*/ 3272 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3273 { 3274 MatFactorInfo tinfo; 3275 3276 PetscFunctionBegin; 3277 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3278 PetscValidType(mat,2); 3279 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 3280 if (info) PetscValidPointer(info,4); 3281 PetscValidPointer(fact,1); 3282 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3283 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3284 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3285 if (!(fact)->ops->choleskyfactorsymbolic) { 3286 MatSolverType stype; 3287 PetscCall(MatFactorGetSolverType(fact,&stype)); 3288 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,stype); 3289 } 3290 MatCheckPreallocated(mat,2); 3291 if (!info) { 3292 PetscCall(MatFactorInfoInitialize(&tinfo)); 3293 info = &tinfo; 3294 } 3295 3296 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3297 PetscCall((fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info)); 3298 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0)); 3299 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3300 PetscFunctionReturn(0); 3301 } 3302 3303 /*@C 3304 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3305 of a symmetric matrix. Call this routine after first calling 3306 MatCholeskyFactorSymbolic(). 3307 3308 Collective on Mat 3309 3310 Input Parameters: 3311 + fact - the factor matrix obtained with MatGetFactor() 3312 . mat - the initial matrix 3313 . info - options for factorization 3314 - fact - the symbolic factor of mat 3315 3316 Notes: 3317 Most users should employ the simplified KSP interface for linear solvers 3318 instead of working directly with matrix algebra routines such as this. 3319 See, e.g., KSPCreate(). 3320 3321 Level: developer 3322 3323 .seealso: `MatCholeskyFactorSymbolic()`, `MatCholeskyFactor()`, `MatLUFactorNumeric()` 3324 3325 Developer Note: fortran interface is not autogenerated as the f90 3326 interface definition cannot be generated correctly [due to MatFactorInfo] 3327 3328 @*/ 3329 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3330 { 3331 MatFactorInfo tinfo; 3332 3333 PetscFunctionBegin; 3334 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3335 PetscValidType(mat,2); 3336 PetscValidPointer(fact,1); 3337 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3338 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3339 PetscCheck((fact)->ops->choleskyfactornumeric,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3340 PetscCheck(mat->rmap->N == (fact)->rmap->N && mat->cmap->N == (fact)->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3341 MatCheckPreallocated(mat,2); 3342 if (!info) { 3343 PetscCall(MatFactorInfoInitialize(&tinfo)); 3344 info = &tinfo; 3345 } 3346 3347 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3348 else PetscCall(PetscLogEventBegin(MAT_CholeskyFactor,mat,fact,0,0)); 3349 PetscCall((fact->ops->choleskyfactornumeric)(fact,mat,info)); 3350 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0)); 3351 else PetscCall(PetscLogEventEnd(MAT_CholeskyFactor,mat,fact,0,0)); 3352 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3353 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3354 PetscFunctionReturn(0); 3355 } 3356 3357 /*@ 3358 MatQRFactor - Performs in-place QR factorization of matrix. 3359 3360 Collective on Mat 3361 3362 Input Parameters: 3363 + mat - the matrix 3364 . col - column permutation 3365 - info - options for factorization, includes 3366 $ fill - expected fill as ratio of original fill. 3367 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3368 $ Run with the option -info to determine an optimal value to use 3369 3370 Notes: 3371 Most users should employ the simplified KSP interface for linear solvers 3372 instead of working directly with matrix algebra routines such as this. 3373 See, e.g., KSPCreate(). 3374 3375 This changes the state of the matrix to a factored matrix; it cannot be used 3376 for example with MatSetValues() unless one first calls MatSetUnfactored(). 3377 3378 Level: developer 3379 3380 .seealso: `MatQRFactorSymbolic()`, `MatQRFactorNumeric()`, `MatLUFactor()`, 3381 `MatSetUnfactored()`, `MatFactorInfo`, `MatGetFactor()` 3382 3383 Developer Note: fortran interface is not autogenerated as the f90 3384 interface definition cannot be generated correctly [due to MatFactorInfo] 3385 3386 @*/ 3387 PetscErrorCode MatQRFactor(Mat mat, IS col, const MatFactorInfo *info) 3388 { 3389 PetscFunctionBegin; 3390 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3391 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,2); 3392 if (info) PetscValidPointer(info,3); 3393 PetscValidType(mat,1); 3394 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3395 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3396 MatCheckPreallocated(mat,1); 3397 PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,col,0,0)); 3398 PetscUseMethod(mat,"MatQRFactor_C", (Mat,IS,const MatFactorInfo*), (mat, col, info)); 3399 PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,col,0,0)); 3400 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 3401 PetscFunctionReturn(0); 3402 } 3403 3404 /*@ 3405 MatQRFactorSymbolic - Performs symbolic QR factorization of matrix. 3406 Call this routine before calling MatQRFactorNumeric(). 3407 3408 Collective on Mat 3409 3410 Input Parameters: 3411 + fact - the factor matrix obtained with MatGetFactor() 3412 . mat - the matrix 3413 . col - column permutation 3414 - info - options for factorization, includes 3415 $ fill - expected fill as ratio of original fill. 3416 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3417 $ Run with the option -info to determine an optimal value to use 3418 3419 Most users should employ the simplified KSP interface for linear solvers 3420 instead of working directly with matrix algebra routines such as this. 3421 See, e.g., KSPCreate(). 3422 3423 Level: developer 3424 3425 .seealso: `MatQRFactor()`, `MatQRFactorNumeric()`, `MatLUFactor()`, `MatFactorInfo`, `MatFactorInfoInitialize()` 3426 3427 Developer Note: fortran interface is not autogenerated as the f90 3428 interface definition cannot be generated correctly [due to MatFactorInfo] 3429 3430 @*/ 3431 PetscErrorCode MatQRFactorSymbolic(Mat fact,Mat mat,IS col,const MatFactorInfo *info) 3432 { 3433 MatFactorInfo tinfo; 3434 3435 PetscFunctionBegin; 3436 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3437 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3438 if (info) PetscValidPointer(info,4); 3439 PetscValidType(mat,2); 3440 PetscValidPointer(fact,1); 3441 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3442 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3443 MatCheckPreallocated(mat,2); 3444 if (!info) { 3445 PetscCall(MatFactorInfoInitialize(&tinfo)); 3446 info = &tinfo; 3447 } 3448 3449 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorSymbolic,fact,mat,col,0)); 3450 PetscUseMethod(fact,"MatQRFactorSymbolic_C", (Mat,Mat,IS,const MatFactorInfo*), (fact, mat, col, info)); 3451 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorSymbolic,fact,mat,col,0)); 3452 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3453 PetscFunctionReturn(0); 3454 } 3455 3456 /*@ 3457 MatQRFactorNumeric - Performs numeric QR factorization of a matrix. 3458 Call this routine after first calling MatQRFactorSymbolic(). 3459 3460 Collective on Mat 3461 3462 Input Parameters: 3463 + fact - the factor matrix obtained with MatGetFactor() 3464 . mat - the matrix 3465 - info - options for factorization 3466 3467 Notes: 3468 See MatQRFactor() for in-place factorization. 3469 3470 Most users should employ the simplified KSP interface for linear solvers 3471 instead of working directly with matrix algebra routines such as this. 3472 See, e.g., KSPCreate(). 3473 3474 Level: developer 3475 3476 .seealso: `MatQRFactorSymbolic()`, `MatLUFactor()` 3477 3478 Developer Note: fortran interface is not autogenerated as the f90 3479 interface definition cannot be generated correctly [due to MatFactorInfo] 3480 3481 @*/ 3482 PetscErrorCode MatQRFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3483 { 3484 MatFactorInfo tinfo; 3485 3486 PetscFunctionBegin; 3487 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 3488 PetscValidType(mat,2); 3489 PetscValidPointer(fact,1); 3490 PetscValidHeaderSpecific(fact,MAT_CLASSID,1); 3491 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3492 PetscCheck(mat->rmap->N == fact->rmap->N && mat->cmap->N == fact->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %" PetscInt_FMT " should = %" PetscInt_FMT " %" PetscInt_FMT " should = %" PetscInt_FMT,mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3493 3494 MatCheckPreallocated(mat,2); 3495 if (!info) { 3496 PetscCall(MatFactorInfoInitialize(&tinfo)); 3497 info = &tinfo; 3498 } 3499 3500 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_QRFactorNumeric,mat,fact,0,0)); 3501 else PetscCall(PetscLogEventBegin(MAT_QRFactor,mat,fact,0,0)); 3502 PetscUseMethod(fact,"MatQRFactorNumeric_C", (Mat,Mat,const MatFactorInfo*), (fact, mat, info)); 3503 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_QRFactorNumeric,mat,fact,0,0)); 3504 else PetscCall(PetscLogEventEnd(MAT_QRFactor,mat,fact,0,0)); 3505 PetscCall(MatViewFromOptions(fact,NULL,"-mat_factor_view")); 3506 PetscCall(PetscObjectStateIncrease((PetscObject)fact)); 3507 PetscFunctionReturn(0); 3508 } 3509 3510 /* ----------------------------------------------------------------*/ 3511 /*@ 3512 MatSolve - Solves A x = b, given a factored matrix. 3513 3514 Neighbor-wise Collective on Mat 3515 3516 Input Parameters: 3517 + mat - the factored matrix 3518 - b - the right-hand-side vector 3519 3520 Output Parameter: 3521 . x - the result vector 3522 3523 Notes: 3524 The vectors b and x cannot be the same. I.e., one cannot 3525 call MatSolve(A,x,x). 3526 3527 Notes: 3528 Most users should employ the simplified KSP interface for linear solvers 3529 instead of working directly with matrix algebra routines such as this. 3530 See, e.g., KSPCreate(). 3531 3532 Level: developer 3533 3534 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3535 @*/ 3536 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3537 { 3538 PetscFunctionBegin; 3539 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3540 PetscValidType(mat,1); 3541 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3542 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3543 PetscCheckSameComm(mat,1,b,2); 3544 PetscCheckSameComm(mat,1,x,3); 3545 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3546 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3547 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3548 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3549 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3550 MatCheckPreallocated(mat,1); 3551 3552 PetscCall(PetscLogEventBegin(MAT_Solve,mat,b,x,0)); 3553 if (mat->factorerrortype) { 3554 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3555 PetscCall(VecSetInf(x)); 3556 } else { 3557 PetscCheck(mat->ops->solve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3558 PetscCall((*mat->ops->solve)(mat,b,x)); 3559 } 3560 PetscCall(PetscLogEventEnd(MAT_Solve,mat,b,x,0)); 3561 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3562 PetscFunctionReturn(0); 3563 } 3564 3565 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans) 3566 { 3567 Vec b,x; 3568 PetscInt N,i; 3569 PetscErrorCode (*f)(Mat,Vec,Vec); 3570 PetscBool Abound,Bneedconv = PETSC_FALSE,Xneedconv = PETSC_FALSE; 3571 3572 PetscFunctionBegin; 3573 if (A->factorerrortype) { 3574 PetscCall(PetscInfo(A,"MatFactorError %d\n",A->factorerrortype)); 3575 PetscCall(MatSetInf(X)); 3576 PetscFunctionReturn(0); 3577 } 3578 f = (!trans || (!A->ops->solvetranspose && A->symmetric)) ? A->ops->solve : A->ops->solvetranspose; 3579 PetscCheck(f,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3580 PetscCall(MatBoundToCPU(A,&Abound)); 3581 if (!Abound) { 3582 PetscCall(PetscObjectTypeCompareAny((PetscObject)B,&Bneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3583 PetscCall(PetscObjectTypeCompareAny((PetscObject)X,&Xneedconv,MATSEQDENSE,MATMPIDENSE,"")); 3584 } 3585 if (Bneedconv) { 3586 PetscCall(MatConvert(B,MATDENSECUDA,MAT_INPLACE_MATRIX,&B)); 3587 } 3588 if (Xneedconv) { 3589 PetscCall(MatConvert(X,MATDENSECUDA,MAT_INPLACE_MATRIX,&X)); 3590 } 3591 PetscCall(MatGetSize(B,NULL,&N)); 3592 for (i=0; i<N; i++) { 3593 PetscCall(MatDenseGetColumnVecRead(B,i,&b)); 3594 PetscCall(MatDenseGetColumnVecWrite(X,i,&x)); 3595 PetscCall((*f)(A,b,x)); 3596 PetscCall(MatDenseRestoreColumnVecWrite(X,i,&x)); 3597 PetscCall(MatDenseRestoreColumnVecRead(B,i,&b)); 3598 } 3599 if (Bneedconv) { 3600 PetscCall(MatConvert(B,MATDENSE,MAT_INPLACE_MATRIX,&B)); 3601 } 3602 if (Xneedconv) { 3603 PetscCall(MatConvert(X,MATDENSE,MAT_INPLACE_MATRIX,&X)); 3604 } 3605 PetscFunctionReturn(0); 3606 } 3607 3608 /*@ 3609 MatMatSolve - Solves A X = B, given a factored matrix. 3610 3611 Neighbor-wise Collective on Mat 3612 3613 Input Parameters: 3614 + A - the factored matrix 3615 - B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS) 3616 3617 Output Parameter: 3618 . X - the result matrix (dense matrix) 3619 3620 Notes: 3621 If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B) except with MKL_CPARDISO; 3622 otherwise, B and X cannot be the same. 3623 3624 Notes: 3625 Most users should usually employ the simplified KSP interface for linear solvers 3626 instead of working directly with matrix algebra routines such as this. 3627 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3628 at a time. 3629 3630 Level: developer 3631 3632 .seealso: `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3633 @*/ 3634 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3635 { 3636 PetscFunctionBegin; 3637 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3638 PetscValidType(A,1); 3639 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3640 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3641 PetscCheckSameComm(A,1,B,2); 3642 PetscCheckSameComm(A,1,X,3); 3643 PetscCheck(A->cmap->N == X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3644 PetscCheck(A->rmap->N == B->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N); 3645 PetscCheck(X->cmap->N == B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3646 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3647 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3648 MatCheckPreallocated(A,1); 3649 3650 PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3651 if (!A->ops->matsolve) { 3652 PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name)); 3653 PetscCall(MatMatSolve_Basic(A,B,X,PETSC_FALSE)); 3654 } else { 3655 PetscCall((*A->ops->matsolve)(A,B,X)); 3656 } 3657 PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3658 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3659 PetscFunctionReturn(0); 3660 } 3661 3662 /*@ 3663 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3664 3665 Neighbor-wise Collective on Mat 3666 3667 Input Parameters: 3668 + A - the factored matrix 3669 - B - the right-hand-side matrix (dense matrix) 3670 3671 Output Parameter: 3672 . X - the result matrix (dense matrix) 3673 3674 Notes: 3675 The matrices B and X cannot be the same. I.e., one cannot 3676 call MatMatSolveTranspose(A,X,X). 3677 3678 Notes: 3679 Most users should usually employ the simplified KSP interface for linear solvers 3680 instead of working directly with matrix algebra routines such as this. 3681 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3682 at a time. 3683 3684 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3685 3686 Level: developer 3687 3688 .seealso: `MatMatSolve()`, `MatLUFactor()`, `MatCholeskyFactor()` 3689 @*/ 3690 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3691 { 3692 PetscFunctionBegin; 3693 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3694 PetscValidType(A,1); 3695 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3696 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3697 PetscCheckSameComm(A,1,B,2); 3698 PetscCheckSameComm(A,1,X,3); 3699 PetscCheck(X != B,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3700 PetscCheck(A->cmap->N == X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3701 PetscCheck(A->rmap->N == B->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,B->rmap->N); 3702 PetscCheck(A->rmap->n == B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->n,B->rmap->n); 3703 PetscCheck(X->cmap->N >= B->cmap->N,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3704 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3705 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3706 MatCheckPreallocated(A,1); 3707 3708 PetscCall(PetscLogEventBegin(MAT_MatSolve,A,B,X,0)); 3709 if (!A->ops->matsolvetranspose) { 3710 PetscCall(PetscInfo(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name)); 3711 PetscCall(MatMatSolve_Basic(A,B,X,PETSC_TRUE)); 3712 } else { 3713 PetscCall((*A->ops->matsolvetranspose)(A,B,X)); 3714 } 3715 PetscCall(PetscLogEventEnd(MAT_MatSolve,A,B,X,0)); 3716 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3717 PetscFunctionReturn(0); 3718 } 3719 3720 /*@ 3721 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3722 3723 Neighbor-wise Collective on Mat 3724 3725 Input Parameters: 3726 + A - the factored matrix 3727 - Bt - the transpose of right-hand-side matrix 3728 3729 Output Parameter: 3730 . X - the result matrix (dense matrix) 3731 3732 Notes: 3733 Most users should usually employ the simplified KSP interface for linear solvers 3734 instead of working directly with matrix algebra routines such as this. 3735 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3736 at a time. 3737 3738 For MUMPS, it only supports centralized sparse compressed column format on the host processor for right hand side matrix. User must create B^T in sparse compressed row format on the host processor and call MatMatTransposeSolve() to implement MUMPS' MatMatSolve(). 3739 3740 Level: developer 3741 3742 .seealso: `MatMatSolve()`, `MatMatSolveTranspose()`, `MatLUFactor()`, `MatCholeskyFactor()` 3743 @*/ 3744 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3745 { 3746 PetscFunctionBegin; 3747 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3748 PetscValidType(A,1); 3749 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3750 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3751 PetscCheckSameComm(A,1,Bt,2); 3752 PetscCheckSameComm(A,1,X,3); 3753 3754 PetscCheck(X != Bt,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3755 PetscCheck(A->cmap->N == X->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->cmap->N,X->rmap->N); 3756 PetscCheck(A->rmap->N == Bt->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %" PetscInt_FMT " %" PetscInt_FMT,A->rmap->N,Bt->cmap->N); 3757 PetscCheck(X->cmap->N >= Bt->rmap->N,PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix"); 3758 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3759 PetscCheck(A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3760 MatCheckPreallocated(A,1); 3761 3762 PetscCheck(A->ops->mattransposesolve,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3763 PetscCall(PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0)); 3764 PetscCall((*A->ops->mattransposesolve)(A,Bt,X)); 3765 PetscCall(PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0)); 3766 PetscCall(PetscObjectStateIncrease((PetscObject)X)); 3767 PetscFunctionReturn(0); 3768 } 3769 3770 /*@ 3771 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3772 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3773 3774 Neighbor-wise Collective on Mat 3775 3776 Input Parameters: 3777 + mat - the factored matrix 3778 - b - the right-hand-side vector 3779 3780 Output Parameter: 3781 . x - the result vector 3782 3783 Notes: 3784 MatSolve() should be used for most applications, as it performs 3785 a forward solve followed by a backward solve. 3786 3787 The vectors b and x cannot be the same, i.e., one cannot 3788 call MatForwardSolve(A,x,x). 3789 3790 For matrix in seqsbaij format with block size larger than 1, 3791 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3792 MatForwardSolve() solves U^T*D y = b, and 3793 MatBackwardSolve() solves U x = y. 3794 Thus they do not provide a symmetric preconditioner. 3795 3796 Most users should employ the simplified KSP interface for linear solvers 3797 instead of working directly with matrix algebra routines such as this. 3798 See, e.g., KSPCreate(). 3799 3800 Level: developer 3801 3802 .seealso: `MatSolve()`, `MatBackwardSolve()` 3803 @*/ 3804 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3805 { 3806 PetscFunctionBegin; 3807 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3808 PetscValidType(mat,1); 3809 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3810 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3811 PetscCheckSameComm(mat,1,b,2); 3812 PetscCheckSameComm(mat,1,x,3); 3813 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3814 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3815 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3816 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3817 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3818 MatCheckPreallocated(mat,1); 3819 3820 PetscCheck(mat->ops->forwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3821 PetscCall(PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0)); 3822 PetscCall((*mat->ops->forwardsolve)(mat,b,x)); 3823 PetscCall(PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0)); 3824 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3825 PetscFunctionReturn(0); 3826 } 3827 3828 /*@ 3829 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3830 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3831 3832 Neighbor-wise Collective on Mat 3833 3834 Input Parameters: 3835 + mat - the factored matrix 3836 - b - the right-hand-side vector 3837 3838 Output Parameter: 3839 . x - the result vector 3840 3841 Notes: 3842 MatSolve() should be used for most applications, as it performs 3843 a forward solve followed by a backward solve. 3844 3845 The vectors b and x cannot be the same. I.e., one cannot 3846 call MatBackwardSolve(A,x,x). 3847 3848 For matrix in seqsbaij format with block size larger than 1, 3849 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3850 MatForwardSolve() solves U^T*D y = b, and 3851 MatBackwardSolve() solves U x = y. 3852 Thus they do not provide a symmetric preconditioner. 3853 3854 Most users should employ the simplified KSP interface for linear solvers 3855 instead of working directly with matrix algebra routines such as this. 3856 See, e.g., KSPCreate(). 3857 3858 Level: developer 3859 3860 .seealso: `MatSolve()`, `MatForwardSolve()` 3861 @*/ 3862 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3863 { 3864 PetscFunctionBegin; 3865 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3866 PetscValidType(mat,1); 3867 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3868 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3869 PetscCheckSameComm(mat,1,b,2); 3870 PetscCheckSameComm(mat,1,x,3); 3871 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3872 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3873 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3874 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3875 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3876 MatCheckPreallocated(mat,1); 3877 3878 PetscCheck(mat->ops->backwardsolve,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3879 PetscCall(PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0)); 3880 PetscCall((*mat->ops->backwardsolve)(mat,b,x)); 3881 PetscCall(PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0)); 3882 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3883 PetscFunctionReturn(0); 3884 } 3885 3886 /*@ 3887 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3888 3889 Neighbor-wise Collective on Mat 3890 3891 Input Parameters: 3892 + mat - the factored matrix 3893 . b - the right-hand-side vector 3894 - y - the vector to be added to 3895 3896 Output Parameter: 3897 . x - the result vector 3898 3899 Notes: 3900 The vectors b and x cannot be the same. I.e., one cannot 3901 call MatSolveAdd(A,x,y,x). 3902 3903 Most users should employ the simplified KSP interface for linear solvers 3904 instead of working directly with matrix algebra routines such as this. 3905 See, e.g., KSPCreate(). 3906 3907 Level: developer 3908 3909 .seealso: `MatSolve()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()` 3910 @*/ 3911 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3912 { 3913 PetscScalar one = 1.0; 3914 Vec tmp; 3915 3916 PetscFunctionBegin; 3917 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3918 PetscValidType(mat,1); 3919 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 3920 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3921 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3922 PetscCheckSameComm(mat,1,b,2); 3923 PetscCheckSameComm(mat,1,y,3); 3924 PetscCheckSameComm(mat,1,x,4); 3925 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3926 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 3927 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 3928 PetscCheck(mat->rmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,y->map->N); 3929 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 3930 PetscCheck(x->map->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,x->map->n,y->map->n); 3931 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3932 MatCheckPreallocated(mat,1); 3933 3934 PetscCall(PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y)); 3935 if (mat->factorerrortype) { 3936 3937 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 3938 PetscCall(VecSetInf(x)); 3939 } else if (mat->ops->solveadd) { 3940 PetscCall((*mat->ops->solveadd)(mat,b,y,x)); 3941 } else { 3942 /* do the solve then the add manually */ 3943 if (x != y) { 3944 PetscCall(MatSolve(mat,b,x)); 3945 PetscCall(VecAXPY(x,one,y)); 3946 } else { 3947 PetscCall(VecDuplicate(x,&tmp)); 3948 PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 3949 PetscCall(VecCopy(x,tmp)); 3950 PetscCall(MatSolve(mat,b,x)); 3951 PetscCall(VecAXPY(x,one,tmp)); 3952 PetscCall(VecDestroy(&tmp)); 3953 } 3954 } 3955 PetscCall(PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y)); 3956 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 3957 PetscFunctionReturn(0); 3958 } 3959 3960 /*@ 3961 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3962 3963 Neighbor-wise Collective on Mat 3964 3965 Input Parameters: 3966 + mat - the factored matrix 3967 - b - the right-hand-side vector 3968 3969 Output Parameter: 3970 . x - the result vector 3971 3972 Notes: 3973 The vectors b and x cannot be the same. I.e., one cannot 3974 call MatSolveTranspose(A,x,x). 3975 3976 Most users should employ the simplified KSP interface for linear solvers 3977 instead of working directly with matrix algebra routines such as this. 3978 See, e.g., KSPCreate(). 3979 3980 Level: developer 3981 3982 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTransposeAdd()` 3983 @*/ 3984 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3985 { 3986 PetscErrorCode (*f)(Mat,Vec,Vec) = (!mat->ops->solvetranspose && mat->symmetric) ? mat->ops->solve : mat->ops->solvetranspose; 3987 3988 PetscFunctionBegin; 3989 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3990 PetscValidType(mat,1); 3991 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3992 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3993 PetscCheckSameComm(mat,1,b,2); 3994 PetscCheckSameComm(mat,1,x,3); 3995 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3996 PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 3997 PetscCheck(mat->cmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,b->map->N); 3998 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3999 MatCheckPreallocated(mat,1); 4000 PetscCall(PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0)); 4001 if (mat->factorerrortype) { 4002 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 4003 PetscCall(VecSetInf(x)); 4004 } else { 4005 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 4006 PetscCall((*f)(mat,b,x)); 4007 } 4008 PetscCall(PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0)); 4009 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4010 PetscFunctionReturn(0); 4011 } 4012 4013 /*@ 4014 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 4015 factored matrix. 4016 4017 Neighbor-wise Collective on Mat 4018 4019 Input Parameters: 4020 + mat - the factored matrix 4021 . b - the right-hand-side vector 4022 - y - the vector to be added to 4023 4024 Output Parameter: 4025 . x - the result vector 4026 4027 Notes: 4028 The vectors b and x cannot be the same. I.e., one cannot 4029 call MatSolveTransposeAdd(A,x,y,x). 4030 4031 Most users should employ the simplified KSP interface for linear solvers 4032 instead of working directly with matrix algebra routines such as this. 4033 See, e.g., KSPCreate(). 4034 4035 Level: developer 4036 4037 .seealso: `MatSolve()`, `MatSolveAdd()`, `MatSolveTranspose()` 4038 @*/ 4039 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 4040 { 4041 PetscScalar one = 1.0; 4042 Vec tmp; 4043 PetscErrorCode (*f)(Mat,Vec,Vec,Vec) = (!mat->ops->solvetransposeadd && mat->symmetric) ? mat->ops->solveadd : mat->ops->solvetransposeadd; 4044 4045 PetscFunctionBegin; 4046 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4047 PetscValidType(mat,1); 4048 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 4049 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4050 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 4051 PetscCheckSameComm(mat,1,b,2); 4052 PetscCheckSameComm(mat,1,y,3); 4053 PetscCheckSameComm(mat,1,x,4); 4054 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 4055 PetscCheck(mat->rmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,x->map->N); 4056 PetscCheck(mat->cmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,b->map->N); 4057 PetscCheck(mat->cmap->N == y->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,y->map->N); 4058 PetscCheck(x->map->n == y->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %" PetscInt_FMT " %" PetscInt_FMT,x->map->n,y->map->n); 4059 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 4060 MatCheckPreallocated(mat,1); 4061 4062 PetscCall(PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y)); 4063 if (mat->factorerrortype) { 4064 PetscCall(PetscInfo(mat,"MatFactorError %d\n",mat->factorerrortype)); 4065 PetscCall(VecSetInf(x)); 4066 } else if (f) { 4067 PetscCall((*f)(mat,b,y,x)); 4068 } else { 4069 /* do the solve then the add manually */ 4070 if (x != y) { 4071 PetscCall(MatSolveTranspose(mat,b,x)); 4072 PetscCall(VecAXPY(x,one,y)); 4073 } else { 4074 PetscCall(VecDuplicate(x,&tmp)); 4075 PetscCall(PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp)); 4076 PetscCall(VecCopy(x,tmp)); 4077 PetscCall(MatSolveTranspose(mat,b,x)); 4078 PetscCall(VecAXPY(x,one,tmp)); 4079 PetscCall(VecDestroy(&tmp)); 4080 } 4081 } 4082 PetscCall(PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y)); 4083 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4084 PetscFunctionReturn(0); 4085 } 4086 /* ----------------------------------------------------------------*/ 4087 4088 /*@ 4089 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 4090 4091 Neighbor-wise Collective on Mat 4092 4093 Input Parameters: 4094 + mat - the matrix 4095 . b - the right hand side 4096 . omega - the relaxation factor 4097 . flag - flag indicating the type of SOR (see below) 4098 . shift - diagonal shift 4099 . its - the number of iterations 4100 - lits - the number of local iterations 4101 4102 Output Parameter: 4103 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 4104 4105 SOR Flags: 4106 + SOR_FORWARD_SWEEP - forward SOR 4107 . SOR_BACKWARD_SWEEP - backward SOR 4108 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 4109 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 4110 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 4111 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 4112 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 4113 upper/lower triangular part of matrix to 4114 vector (with omega) 4115 - SOR_ZERO_INITIAL_GUESS - zero initial guess 4116 4117 Notes: 4118 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 4119 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 4120 on each processor. 4121 4122 Application programmers will not generally use MatSOR() directly, 4123 but instead will employ the KSP/PC interface. 4124 4125 Notes: 4126 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 4127 4128 Notes for Advanced Users: 4129 The flags are implemented as bitwise inclusive or operations. 4130 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 4131 to specify a zero initial guess for SSOR. 4132 4133 Most users should employ the simplified KSP interface for linear solvers 4134 instead of working directly with matrix algebra routines such as this. 4135 See, e.g., KSPCreate(). 4136 4137 Vectors x and b CANNOT be the same 4138 4139 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 4140 4141 Level: developer 4142 4143 @*/ 4144 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 4145 { 4146 PetscFunctionBegin; 4147 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4148 PetscValidType(mat,1); 4149 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 4150 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 4151 PetscCheckSameComm(mat,1,b,2); 4152 PetscCheckSameComm(mat,1,x,8); 4153 PetscCheck(mat->ops->sor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4154 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4155 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4156 PetscCheck(mat->cmap->N == x->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->cmap->N,x->map->N); 4157 PetscCheck(mat->rmap->N == b->map->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->N,b->map->N); 4158 PetscCheck(mat->rmap->n == b->map->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %" PetscInt_FMT " %" PetscInt_FMT,mat->rmap->n,b->map->n); 4159 PetscCheck(its > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " positive",its); 4160 PetscCheck(lits > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %" PetscInt_FMT " positive",lits); 4161 PetscCheck(b != x,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 4162 4163 MatCheckPreallocated(mat,1); 4164 PetscCall(PetscLogEventBegin(MAT_SOR,mat,b,x,0)); 4165 PetscCall((*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x)); 4166 PetscCall(PetscLogEventEnd(MAT_SOR,mat,b,x,0)); 4167 PetscCall(PetscObjectStateIncrease((PetscObject)x)); 4168 PetscFunctionReturn(0); 4169 } 4170 4171 /* 4172 Default matrix copy routine. 4173 */ 4174 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 4175 { 4176 PetscInt i,rstart = 0,rend = 0,nz; 4177 const PetscInt *cwork; 4178 const PetscScalar *vwork; 4179 4180 PetscFunctionBegin; 4181 if (B->assembled) PetscCall(MatZeroEntries(B)); 4182 if (str == SAME_NONZERO_PATTERN) { 4183 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 4184 for (i=rstart; i<rend; i++) { 4185 PetscCall(MatGetRow(A,i,&nz,&cwork,&vwork)); 4186 PetscCall(MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES)); 4187 PetscCall(MatRestoreRow(A,i,&nz,&cwork,&vwork)); 4188 } 4189 } else { 4190 PetscCall(MatAYPX(B,0.0,A,str)); 4191 } 4192 PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 4193 PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 4194 PetscFunctionReturn(0); 4195 } 4196 4197 /*@ 4198 MatCopy - Copies a matrix to another matrix. 4199 4200 Collective on Mat 4201 4202 Input Parameters: 4203 + A - the matrix 4204 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 4205 4206 Output Parameter: 4207 . B - where the copy is put 4208 4209 Notes: 4210 If you use SAME_NONZERO_PATTERN then the two matrices must have the same nonzero pattern or the routine will crash. 4211 4212 MatCopy() copies the matrix entries of a matrix to another existing 4213 matrix (after first zeroing the second matrix). A related routine is 4214 MatConvert(), which first creates a new matrix and then copies the data. 4215 4216 Level: intermediate 4217 4218 .seealso: `MatConvert()`, `MatDuplicate()` 4219 @*/ 4220 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 4221 { 4222 PetscInt i; 4223 4224 PetscFunctionBegin; 4225 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4226 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4227 PetscValidType(A,1); 4228 PetscValidType(B,2); 4229 PetscCheckSameComm(A,1,B,2); 4230 MatCheckPreallocated(B,2); 4231 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4232 PetscCheck(!A->factortype,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4233 PetscCheck(A->rmap->N == B->rmap->N && A->cmap->N == B->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%" PetscInt_FMT ",%" PetscInt_FMT ") (%" PetscInt_FMT ",%" PetscInt_FMT ")",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N); 4234 MatCheckPreallocated(A,1); 4235 if (A == B) PetscFunctionReturn(0); 4236 4237 PetscCall(PetscLogEventBegin(MAT_Copy,A,B,0,0)); 4238 if (A->ops->copy) { 4239 PetscCall((*A->ops->copy)(A,B,str)); 4240 } else { /* generic conversion */ 4241 PetscCall(MatCopy_Basic(A,B,str)); 4242 } 4243 4244 B->stencil.dim = A->stencil.dim; 4245 B->stencil.noc = A->stencil.noc; 4246 for (i=0; i<=A->stencil.dim; i++) { 4247 B->stencil.dims[i] = A->stencil.dims[i]; 4248 B->stencil.starts[i] = A->stencil.starts[i]; 4249 } 4250 4251 PetscCall(PetscLogEventEnd(MAT_Copy,A,B,0,0)); 4252 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4253 PetscFunctionReturn(0); 4254 } 4255 4256 /*@C 4257 MatConvert - Converts a matrix to another matrix, either of the same 4258 or different type. 4259 4260 Collective on Mat 4261 4262 Input Parameters: 4263 + mat - the matrix 4264 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4265 same type as the original matrix. 4266 - reuse - denotes if the destination matrix is to be created or reused. 4267 Use MAT_INPLACE_MATRIX for inplace conversion (that is when you want the input mat to be changed to contain the matrix in the new format), otherwise use 4268 MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX (can only be used after the first call was made with MAT_INITIAL_MATRIX, causes the matrix space in M to be reused). 4269 4270 Output Parameter: 4271 . M - pointer to place new matrix 4272 4273 Notes: 4274 MatConvert() first creates a new matrix and then copies the data from 4275 the first matrix. A related routine is MatCopy(), which copies the matrix 4276 entries of one matrix to another already existing matrix context. 4277 4278 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4279 the MPI communicator of the generated matrix is always the same as the communicator 4280 of the input matrix. 4281 4282 Level: intermediate 4283 4284 .seealso: `MatCopy()`, `MatDuplicate()` 4285 @*/ 4286 PetscErrorCode MatConvert(Mat mat,MatType newtype,MatReuse reuse,Mat *M) 4287 { 4288 PetscBool sametype,issame,flg,issymmetric,ishermitian; 4289 char convname[256],mtype[256]; 4290 Mat B; 4291 4292 PetscFunctionBegin; 4293 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4294 PetscValidType(mat,1); 4295 PetscValidPointer(M,4); 4296 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4297 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4298 MatCheckPreallocated(mat,1); 4299 4300 PetscCall(PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,sizeof(mtype),&flg)); 4301 if (flg) newtype = mtype; 4302 4303 PetscCall(PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype)); 4304 PetscCall(PetscStrcmp(newtype,"same",&issame)); 4305 PetscCheck(!(reuse == MAT_INPLACE_MATRIX) || !(mat != *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4306 PetscCheck(!(reuse == MAT_REUSE_MATRIX) || !(mat == *M),PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX"); 4307 4308 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4309 PetscCall(PetscInfo(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4310 PetscFunctionReturn(0); 4311 } 4312 4313 /* Cache Mat options because some converter use MatHeaderReplace */ 4314 issymmetric = mat->symmetric; 4315 ishermitian = mat->hermitian; 4316 4317 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4318 PetscCall(PetscInfo(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame)); 4319 PetscCall((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M)); 4320 } else { 4321 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4322 const char *prefix[3] = {"seq","mpi",""}; 4323 PetscInt i; 4324 /* 4325 Order of precedence: 4326 0) See if newtype is a superclass of the current matrix. 4327 1) See if a specialized converter is known to the current matrix. 4328 2) See if a specialized converter is known to the desired matrix class. 4329 3) See if a good general converter is registered for the desired class 4330 (as of 6/27/03 only MATMPIADJ falls into this category). 4331 4) See if a good general converter is known for the current matrix. 4332 5) Use a really basic converter. 4333 */ 4334 4335 /* 0) See if newtype is a superclass of the current matrix. 4336 i.e mat is mpiaij and newtype is aij */ 4337 for (i=0; i<2; i++) { 4338 PetscCall(PetscStrncpy(convname,prefix[i],sizeof(convname))); 4339 PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 4340 PetscCall(PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg)); 4341 PetscCall(PetscInfo(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg)); 4342 if (flg) { 4343 if (reuse == MAT_INPLACE_MATRIX) { 4344 PetscCall(PetscInfo(mat,"Early return\n")); 4345 PetscFunctionReturn(0); 4346 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4347 PetscCall(PetscInfo(mat,"Calling MatDuplicate\n")); 4348 PetscCall((*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M)); 4349 PetscFunctionReturn(0); 4350 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4351 PetscCall(PetscInfo(mat,"Calling MatCopy\n")); 4352 PetscCall(MatCopy(mat,*M,SAME_NONZERO_PATTERN)); 4353 PetscFunctionReturn(0); 4354 } 4355 } 4356 } 4357 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4358 for (i=0; i<3; i++) { 4359 PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4360 PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4361 PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 4362 PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4363 PetscCall(PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname))); 4364 PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 4365 PetscCall(PetscObjectQueryFunction((PetscObject)mat,convname,&conv)); 4366 PetscCall(PetscInfo(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv)); 4367 if (conv) goto foundconv; 4368 } 4369 4370 /* 2) See if a specialized converter is known to the desired matrix class. */ 4371 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&B)); 4372 PetscCall(MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 4373 PetscCall(MatSetType(B,newtype)); 4374 for (i=0; i<3; i++) { 4375 PetscCall(PetscStrncpy(convname,"MatConvert_",sizeof(convname))); 4376 PetscCall(PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname))); 4377 PetscCall(PetscStrlcat(convname,"_",sizeof(convname))); 4378 PetscCall(PetscStrlcat(convname,prefix[i],sizeof(convname))); 4379 PetscCall(PetscStrlcat(convname,newtype,sizeof(convname))); 4380 PetscCall(PetscStrlcat(convname,"_C",sizeof(convname))); 4381 PetscCall(PetscObjectQueryFunction((PetscObject)B,convname,&conv)); 4382 PetscCall(PetscInfo(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv)); 4383 if (conv) { 4384 PetscCall(MatDestroy(&B)); 4385 goto foundconv; 4386 } 4387 } 4388 4389 /* 3) See if a good general converter is registered for the desired class */ 4390 conv = B->ops->convertfrom; 4391 PetscCall(PetscInfo(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv)); 4392 PetscCall(MatDestroy(&B)); 4393 if (conv) goto foundconv; 4394 4395 /* 4) See if a good general converter is known for the current matrix */ 4396 if (mat->ops->convert) conv = mat->ops->convert; 4397 PetscCall(PetscInfo(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv)); 4398 if (conv) goto foundconv; 4399 4400 /* 5) Use a really basic converter. */ 4401 PetscCall(PetscInfo(mat,"Using MatConvert_Basic\n")); 4402 conv = MatConvert_Basic; 4403 4404 foundconv: 4405 PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4406 PetscCall((*conv)(mat,newtype,reuse,M)); 4407 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4408 /* the block sizes must be same if the mappings are copied over */ 4409 (*M)->rmap->bs = mat->rmap->bs; 4410 (*M)->cmap->bs = mat->cmap->bs; 4411 PetscCall(PetscObjectReference((PetscObject)mat->rmap->mapping)); 4412 PetscCall(PetscObjectReference((PetscObject)mat->cmap->mapping)); 4413 (*M)->rmap->mapping = mat->rmap->mapping; 4414 (*M)->cmap->mapping = mat->cmap->mapping; 4415 } 4416 (*M)->stencil.dim = mat->stencil.dim; 4417 (*M)->stencil.noc = mat->stencil.noc; 4418 for (i=0; i<=mat->stencil.dim; i++) { 4419 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4420 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4421 } 4422 PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4423 } 4424 PetscCall(PetscObjectStateIncrease((PetscObject)*M)); 4425 4426 /* Copy Mat options */ 4427 if (issymmetric) PetscCall(MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE)); 4428 if (ishermitian) PetscCall(MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE)); 4429 PetscFunctionReturn(0); 4430 } 4431 4432 /*@C 4433 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4434 4435 Not Collective 4436 4437 Input Parameter: 4438 . mat - the matrix, must be a factored matrix 4439 4440 Output Parameter: 4441 . type - the string name of the package (do not free this string) 4442 4443 Notes: 4444 In Fortran you pass in a empty string and the package name will be copied into it. 4445 (Make sure the string is long enough) 4446 4447 Level: intermediate 4448 4449 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4450 @*/ 4451 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4452 { 4453 PetscErrorCode (*conv)(Mat,MatSolverType*); 4454 4455 PetscFunctionBegin; 4456 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4457 PetscValidType(mat,1); 4458 PetscValidPointer(type,2); 4459 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4460 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv)); 4461 if (conv) PetscCall((*conv)(mat,type)); 4462 else *type = MATSOLVERPETSC; 4463 PetscFunctionReturn(0); 4464 } 4465 4466 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4467 struct _MatSolverTypeForSpecifcType { 4468 MatType mtype; 4469 /* no entry for MAT_FACTOR_NONE */ 4470 PetscErrorCode (*createfactor[MAT_FACTOR_NUM_TYPES-1])(Mat,MatFactorType,Mat*); 4471 MatSolverTypeForSpecifcType next; 4472 }; 4473 4474 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4475 struct _MatSolverTypeHolder { 4476 char *name; 4477 MatSolverTypeForSpecifcType handlers; 4478 MatSolverTypeHolder next; 4479 }; 4480 4481 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4482 4483 /*@C 4484 MatSolverTypeRegister - Registers a MatSolverType that works for a particular matrix type 4485 4486 Input Parameters: 4487 + package - name of the package, for example petsc or superlu 4488 . mtype - the matrix type that works with this package 4489 . ftype - the type of factorization supported by the package 4490 - createfactor - routine that will create the factored matrix ready to be used 4491 4492 Level: intermediate 4493 4494 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()` 4495 @*/ 4496 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*createfactor)(Mat,MatFactorType,Mat*)) 4497 { 4498 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4499 PetscBool flg; 4500 MatSolverTypeForSpecifcType inext,iprev = NULL; 4501 4502 PetscFunctionBegin; 4503 PetscCall(MatInitializePackage()); 4504 if (!next) { 4505 PetscCall(PetscNew(&MatSolverTypeHolders)); 4506 PetscCall(PetscStrallocpy(package,&MatSolverTypeHolders->name)); 4507 PetscCall(PetscNew(&MatSolverTypeHolders->handlers)); 4508 PetscCall(PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype)); 4509 MatSolverTypeHolders->handlers->createfactor[(int)ftype-1] = createfactor; 4510 PetscFunctionReturn(0); 4511 } 4512 while (next) { 4513 PetscCall(PetscStrcasecmp(package,next->name,&flg)); 4514 if (flg) { 4515 PetscCheck(next->handlers,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4516 inext = next->handlers; 4517 while (inext) { 4518 PetscCall(PetscStrcasecmp(mtype,inext->mtype,&flg)); 4519 if (flg) { 4520 inext->createfactor[(int)ftype-1] = createfactor; 4521 PetscFunctionReturn(0); 4522 } 4523 iprev = inext; 4524 inext = inext->next; 4525 } 4526 PetscCall(PetscNew(&iprev->next)); 4527 PetscCall(PetscStrallocpy(mtype,(char **)&iprev->next->mtype)); 4528 iprev->next->createfactor[(int)ftype-1] = createfactor; 4529 PetscFunctionReturn(0); 4530 } 4531 prev = next; 4532 next = next->next; 4533 } 4534 PetscCall(PetscNew(&prev->next)); 4535 PetscCall(PetscStrallocpy(package,&prev->next->name)); 4536 PetscCall(PetscNew(&prev->next->handlers)); 4537 PetscCall(PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype)); 4538 prev->next->handlers->createfactor[(int)ftype-1] = createfactor; 4539 PetscFunctionReturn(0); 4540 } 4541 4542 /*@C 4543 MatSolverTypeGet - Gets the function that creates the factor matrix if it exist 4544 4545 Input Parameters: 4546 + type - name of the package, for example petsc or superlu 4547 . ftype - the type of factorization supported by the type 4548 - mtype - the matrix type that works with this type 4549 4550 Output Parameters: 4551 + foundtype - PETSC_TRUE if the type was registered 4552 . foundmtype - PETSC_TRUE if the type supports the requested mtype 4553 - createfactor - routine that will create the factored matrix ready to be used or NULL if not found 4554 4555 Level: intermediate 4556 4557 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatSolverTypeRegister()`, `MatGetFactor()` 4558 @*/ 4559 PetscErrorCode MatSolverTypeGet(MatSolverType type,MatType mtype,MatFactorType ftype,PetscBool *foundtype,PetscBool *foundmtype,PetscErrorCode (**createfactor)(Mat,MatFactorType,Mat*)) 4560 { 4561 MatSolverTypeHolder next = MatSolverTypeHolders; 4562 PetscBool flg; 4563 MatSolverTypeForSpecifcType inext; 4564 4565 PetscFunctionBegin; 4566 if (foundtype) *foundtype = PETSC_FALSE; 4567 if (foundmtype) *foundmtype = PETSC_FALSE; 4568 if (createfactor) *createfactor = NULL; 4569 4570 if (type) { 4571 while (next) { 4572 PetscCall(PetscStrcasecmp(type,next->name,&flg)); 4573 if (flg) { 4574 if (foundtype) *foundtype = PETSC_TRUE; 4575 inext = next->handlers; 4576 while (inext) { 4577 PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4578 if (flg) { 4579 if (foundmtype) *foundmtype = PETSC_TRUE; 4580 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4581 PetscFunctionReturn(0); 4582 } 4583 inext = inext->next; 4584 } 4585 } 4586 next = next->next; 4587 } 4588 } else { 4589 while (next) { 4590 inext = next->handlers; 4591 while (inext) { 4592 PetscCall(PetscStrcmp(mtype,inext->mtype,&flg)); 4593 if (flg && inext->createfactor[(int)ftype-1]) { 4594 if (foundtype) *foundtype = PETSC_TRUE; 4595 if (foundmtype) *foundmtype = PETSC_TRUE; 4596 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4597 PetscFunctionReturn(0); 4598 } 4599 inext = inext->next; 4600 } 4601 next = next->next; 4602 } 4603 /* try with base classes inext->mtype */ 4604 next = MatSolverTypeHolders; 4605 while (next) { 4606 inext = next->handlers; 4607 while (inext) { 4608 PetscCall(PetscStrbeginswith(mtype,inext->mtype,&flg)); 4609 if (flg && inext->createfactor[(int)ftype-1]) { 4610 if (foundtype) *foundtype = PETSC_TRUE; 4611 if (foundmtype) *foundmtype = PETSC_TRUE; 4612 if (createfactor) *createfactor = inext->createfactor[(int)ftype-1]; 4613 PetscFunctionReturn(0); 4614 } 4615 inext = inext->next; 4616 } 4617 next = next->next; 4618 } 4619 } 4620 PetscFunctionReturn(0); 4621 } 4622 4623 PetscErrorCode MatSolverTypeDestroy(void) 4624 { 4625 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4626 MatSolverTypeForSpecifcType inext,iprev; 4627 4628 PetscFunctionBegin; 4629 while (next) { 4630 PetscCall(PetscFree(next->name)); 4631 inext = next->handlers; 4632 while (inext) { 4633 PetscCall(PetscFree(inext->mtype)); 4634 iprev = inext; 4635 inext = inext->next; 4636 PetscCall(PetscFree(iprev)); 4637 } 4638 prev = next; 4639 next = next->next; 4640 PetscCall(PetscFree(prev)); 4641 } 4642 MatSolverTypeHolders = NULL; 4643 PetscFunctionReturn(0); 4644 } 4645 4646 /*@C 4647 MatFactorGetCanUseOrdering - Indicates if the factorization can use the ordering provided in MatLUFactorSymbolic(), MatCholeskyFactorSymbolic() 4648 4649 Logically Collective on Mat 4650 4651 Input Parameters: 4652 . mat - the matrix 4653 4654 Output Parameters: 4655 . flg - PETSC_TRUE if uses the ordering 4656 4657 Notes: 4658 Most internal PETSc factorizations use the ordering passed to the factorization routine but external 4659 packages do not, thus we want to skip generating the ordering when it is not needed or used. 4660 4661 Level: developer 4662 4663 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4664 @*/ 4665 PetscErrorCode MatFactorGetCanUseOrdering(Mat mat, PetscBool *flg) 4666 { 4667 PetscFunctionBegin; 4668 *flg = mat->canuseordering; 4669 PetscFunctionReturn(0); 4670 } 4671 4672 /*@C 4673 MatFactorGetPreferredOrdering - The preferred ordering for a particular matrix factor object 4674 4675 Logically Collective on Mat 4676 4677 Input Parameters: 4678 . mat - the matrix 4679 4680 Output Parameters: 4681 . otype - the preferred type 4682 4683 Level: developer 4684 4685 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatGetFactor()`, `MatLUFactorSymbolic()`, `MatCholeskyFactorSymbolic()` 4686 @*/ 4687 PetscErrorCode MatFactorGetPreferredOrdering(Mat mat, MatFactorType ftype, MatOrderingType *otype) 4688 { 4689 PetscFunctionBegin; 4690 *otype = mat->preferredordering[ftype]; 4691 PetscCheck(*otype,PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatFactor did not have a preferred ordering"); 4692 PetscFunctionReturn(0); 4693 } 4694 4695 /*@C 4696 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4697 4698 Collective on Mat 4699 4700 Input Parameters: 4701 + mat - the matrix 4702 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4703 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4704 4705 Output Parameters: 4706 . f - the factor matrix used with MatXXFactorSymbolic() calls 4707 4708 Notes: 4709 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4710 such as pastix, superlu, mumps etc. 4711 4712 PETSc must have been ./configure to use the external solver, using the option --download-package 4713 4714 Some of the packages have options for controlling the factorization, these are in the form -prefix_mat_packagename_packageoption 4715 where prefix is normally obtained from the calling `KSP`/`PC`. If `MatGetFactor()` is called directly one can set 4716 call `MatSetOptionsPrefixFactor()` on the originating matrix or `MatSetOptionsPrefix()` on the resulting factor matrix. 4717 4718 Developer Notes: 4719 This should actually be called MatCreateFactor() since it creates a new factor object 4720 4721 Level: intermediate 4722 4723 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactorAvailable()`, `MatFactorGetCanUseOrdering()`, `MatSolverTypeRegister()` 4724 @*/ 4725 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4726 { 4727 PetscBool foundtype,foundmtype; 4728 PetscErrorCode (*conv)(Mat,MatFactorType,Mat*); 4729 4730 PetscFunctionBegin; 4731 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4732 PetscValidType(mat,1); 4733 4734 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4735 MatCheckPreallocated(mat,1); 4736 4737 PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundtype,&foundmtype,&conv)); 4738 if (!foundtype) { 4739 if (type) { 4740 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); 4741 } else { 4742 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); 4743 } 4744 } 4745 PetscCheck(foundmtype,PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4746 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); 4747 4748 PetscCall((*conv)(mat,ftype,f)); 4749 if (mat->factorprefix) PetscCall(MatSetOptionsPrefix(*f,mat->factorprefix)); 4750 PetscFunctionReturn(0); 4751 } 4752 4753 /*@C 4754 MatGetFactorAvailable - Returns a a flag if matrix supports particular type and factor type 4755 4756 Not Collective 4757 4758 Input Parameters: 4759 + mat - the matrix 4760 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4761 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4762 4763 Output Parameter: 4764 . flg - PETSC_TRUE if the factorization is available 4765 4766 Notes: 4767 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4768 such as pastix, superlu, mumps etc. 4769 4770 PETSc must have been ./configure to use the external solver, using the option --download-package 4771 4772 Developer Notes: 4773 This should actually be called MatCreateFactorAvailable() since MatGetFactor() creates a new factor object 4774 4775 Level: intermediate 4776 4777 .seealso: `MatCopy()`, `MatDuplicate()`, `MatGetFactor()`, `MatSolverTypeRegister()` 4778 @*/ 4779 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4780 { 4781 PetscErrorCode (*gconv)(Mat,MatFactorType,Mat*); 4782 4783 PetscFunctionBegin; 4784 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4785 PetscValidType(mat,1); 4786 PetscValidBoolPointer(flg,4); 4787 4788 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4789 MatCheckPreallocated(mat,1); 4790 4791 PetscCall(MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv)); 4792 *flg = gconv ? PETSC_TRUE : PETSC_FALSE; 4793 PetscFunctionReturn(0); 4794 } 4795 4796 /*@ 4797 MatDuplicate - Duplicates a matrix including the non-zero structure. 4798 4799 Collective on Mat 4800 4801 Input Parameters: 4802 + mat - the matrix 4803 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4804 See the manual page for MatDuplicateOption for an explanation of these options. 4805 4806 Output Parameter: 4807 . M - pointer to place new matrix 4808 4809 Level: intermediate 4810 4811 Notes: 4812 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4813 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. 4814 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. 4815 4816 .seealso: `MatCopy()`, `MatConvert()`, `MatDuplicateOption` 4817 @*/ 4818 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4819 { 4820 Mat B; 4821 VecType vtype; 4822 PetscInt i; 4823 PetscObject dm; 4824 void (*viewf)(void); 4825 4826 PetscFunctionBegin; 4827 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4828 PetscValidType(mat,1); 4829 PetscValidPointer(M,3); 4830 PetscCheck(op != MAT_COPY_VALUES || mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4831 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4832 MatCheckPreallocated(mat,1); 4833 4834 *M = NULL; 4835 PetscCheck(mat->ops->duplicate,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s",((PetscObject)mat)->type_name); 4836 PetscCall(PetscLogEventBegin(MAT_Convert,mat,0,0,0)); 4837 PetscCall((*mat->ops->duplicate)(mat,op,M)); 4838 PetscCall(PetscLogEventEnd(MAT_Convert,mat,0,0,0)); 4839 B = *M; 4840 4841 PetscCall(MatGetOperation(mat,MATOP_VIEW,&viewf)); 4842 if (viewf) PetscCall(MatSetOperation(B,MATOP_VIEW,viewf)); 4843 PetscCall(MatGetVecType(mat,&vtype)); 4844 PetscCall(MatSetVecType(B,vtype)); 4845 4846 B->stencil.dim = mat->stencil.dim; 4847 B->stencil.noc = mat->stencil.noc; 4848 for (i=0; i<=mat->stencil.dim; i++) { 4849 B->stencil.dims[i] = mat->stencil.dims[i]; 4850 B->stencil.starts[i] = mat->stencil.starts[i]; 4851 } 4852 4853 B->nooffproczerorows = mat->nooffproczerorows; 4854 B->nooffprocentries = mat->nooffprocentries; 4855 4856 PetscCall(PetscObjectQuery((PetscObject) mat, "__PETSc_dm", &dm)); 4857 if (dm) { 4858 PetscCall(PetscObjectCompose((PetscObject) B, "__PETSc_dm", dm)); 4859 } 4860 PetscCall(PetscObjectStateIncrease((PetscObject)B)); 4861 PetscFunctionReturn(0); 4862 } 4863 4864 /*@ 4865 MatGetDiagonal - Gets the diagonal of a matrix. 4866 4867 Logically Collective on Mat 4868 4869 Input Parameters: 4870 + mat - the matrix 4871 - v - the vector for storing the diagonal 4872 4873 Output Parameter: 4874 . v - the diagonal of the matrix 4875 4876 Level: intermediate 4877 4878 Note: 4879 Currently only correct in parallel for square matrices. 4880 4881 .seealso: `MatGetRow()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()` 4882 @*/ 4883 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4884 { 4885 PetscFunctionBegin; 4886 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4887 PetscValidType(mat,1); 4888 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4889 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4890 PetscCheck(mat->ops->getdiagonal,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4891 MatCheckPreallocated(mat,1); 4892 4893 PetscCall((*mat->ops->getdiagonal)(mat,v)); 4894 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4895 PetscFunctionReturn(0); 4896 } 4897 4898 /*@C 4899 MatGetRowMin - Gets the minimum value (of the real part) of each 4900 row of the matrix 4901 4902 Logically Collective on Mat 4903 4904 Input Parameter: 4905 . mat - the matrix 4906 4907 Output Parameters: 4908 + v - the vector for storing the maximums 4909 - idx - the indices of the column found for each row (optional) 4910 4911 Level: intermediate 4912 4913 Notes: 4914 The result of this call are the same as if one converted the matrix to dense format 4915 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4916 4917 This code is only implemented for a couple of matrix formats. 4918 4919 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, 4920 `MatGetRowMax()` 4921 @*/ 4922 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4923 { 4924 PetscFunctionBegin; 4925 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4926 PetscValidType(mat,1); 4927 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4928 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4929 4930 if (!mat->cmap->N) { 4931 PetscCall(VecSet(v,PETSC_MAX_REAL)); 4932 if (idx) { 4933 PetscInt i,m = mat->rmap->n; 4934 for (i=0; i<m; i++) idx[i] = -1; 4935 } 4936 } else { 4937 PetscCheck(mat->ops->getrowmin,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4938 MatCheckPreallocated(mat,1); 4939 } 4940 PetscCall((*mat->ops->getrowmin)(mat,v,idx)); 4941 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4942 PetscFunctionReturn(0); 4943 } 4944 4945 /*@C 4946 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4947 row of the matrix 4948 4949 Logically Collective on Mat 4950 4951 Input Parameter: 4952 . mat - the matrix 4953 4954 Output Parameters: 4955 + v - the vector for storing the minimums 4956 - idx - the indices of the column found for each row (or NULL if not needed) 4957 4958 Level: intermediate 4959 4960 Notes: 4961 if a row is completely empty or has only 0.0 values then the idx[] value for that 4962 row is 0 (the first column). 4963 4964 This code is only implemented for a couple of matrix formats. 4965 4966 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 4967 @*/ 4968 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4969 { 4970 PetscFunctionBegin; 4971 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4972 PetscValidType(mat,1); 4973 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4974 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4975 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4976 4977 if (!mat->cmap->N) { 4978 PetscCall(VecSet(v,0.0)); 4979 if (idx) { 4980 PetscInt i,m = mat->rmap->n; 4981 for (i=0; i<m; i++) idx[i] = -1; 4982 } 4983 } else { 4984 PetscCheck(mat->ops->getrowminabs,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4985 MatCheckPreallocated(mat,1); 4986 if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n)); 4987 PetscCall((*mat->ops->getrowminabs)(mat,v,idx)); 4988 } 4989 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 4990 PetscFunctionReturn(0); 4991 } 4992 4993 /*@C 4994 MatGetRowMax - Gets the maximum value (of the real part) of each 4995 row of the matrix 4996 4997 Logically Collective on Mat 4998 4999 Input Parameter: 5000 . mat - the matrix 5001 5002 Output Parameters: 5003 + v - the vector for storing the maximums 5004 - idx - the indices of the column found for each row (optional) 5005 5006 Level: intermediate 5007 5008 Notes: 5009 The result of this call are the same as if one converted the matrix to dense format 5010 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 5011 5012 This code is only implemented for a couple of matrix formats. 5013 5014 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMaxAbs()`, `MatGetRowMin()` 5015 @*/ 5016 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 5017 { 5018 PetscFunctionBegin; 5019 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5020 PetscValidType(mat,1); 5021 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5022 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5023 5024 if (!mat->cmap->N) { 5025 PetscCall(VecSet(v,PETSC_MIN_REAL)); 5026 if (idx) { 5027 PetscInt i,m = mat->rmap->n; 5028 for (i=0; i<m; i++) idx[i] = -1; 5029 } 5030 } else { 5031 PetscCheck(mat->ops->getrowmax,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5032 MatCheckPreallocated(mat,1); 5033 PetscCall((*mat->ops->getrowmax)(mat,v,idx)); 5034 } 5035 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5036 PetscFunctionReturn(0); 5037 } 5038 5039 /*@C 5040 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 5041 row of the matrix 5042 5043 Logically Collective on Mat 5044 5045 Input Parameter: 5046 . mat - the matrix 5047 5048 Output Parameters: 5049 + v - the vector for storing the maximums 5050 - idx - the indices of the column found for each row (or NULL if not needed) 5051 5052 Level: intermediate 5053 5054 Notes: 5055 if a row is completely empty or has only 0.0 values then the idx[] value for that 5056 row is 0 (the first column). 5057 5058 This code is only implemented for a couple of matrix formats. 5059 5060 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 5061 @*/ 5062 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 5063 { 5064 PetscFunctionBegin; 5065 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5066 PetscValidType(mat,1); 5067 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5068 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5069 5070 if (!mat->cmap->N) { 5071 PetscCall(VecSet(v,0.0)); 5072 if (idx) { 5073 PetscInt i,m = mat->rmap->n; 5074 for (i=0; i<m; i++) idx[i] = -1; 5075 } 5076 } else { 5077 PetscCheck(mat->ops->getrowmaxabs,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5078 MatCheckPreallocated(mat,1); 5079 if (idx) PetscCall(PetscArrayzero(idx,mat->rmap->n)); 5080 PetscCall((*mat->ops->getrowmaxabs)(mat,v,idx)); 5081 } 5082 PetscCall(PetscObjectStateIncrease((PetscObject)v)); 5083 PetscFunctionReturn(0); 5084 } 5085 5086 /*@ 5087 MatGetRowSum - Gets the sum of each row of the matrix 5088 5089 Logically or Neighborhood Collective on Mat 5090 5091 Input Parameters: 5092 . mat - the matrix 5093 5094 Output Parameter: 5095 . v - the vector for storing the sum of rows 5096 5097 Level: intermediate 5098 5099 Notes: 5100 This code is slow since it is not currently specialized for different formats 5101 5102 .seealso: `MatGetDiagonal()`, `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRowMax()`, `MatGetRowMin()` 5103 @*/ 5104 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 5105 { 5106 Vec ones; 5107 5108 PetscFunctionBegin; 5109 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5110 PetscValidType(mat,1); 5111 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 5112 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5113 MatCheckPreallocated(mat,1); 5114 PetscCall(MatCreateVecs(mat,&ones,NULL)); 5115 PetscCall(VecSet(ones,1.)); 5116 PetscCall(MatMult(mat,ones,v)); 5117 PetscCall(VecDestroy(&ones)); 5118 PetscFunctionReturn(0); 5119 } 5120 5121 /*@ 5122 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 5123 5124 Collective on Mat 5125 5126 Input Parameters: 5127 + mat - the matrix to transpose 5128 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5129 5130 Output Parameter: 5131 . B - the transpose 5132 5133 Notes: 5134 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 5135 5136 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 5137 5138 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 5139 5140 Level: intermediate 5141 5142 .seealso: `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5143 @*/ 5144 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 5145 { 5146 PetscFunctionBegin; 5147 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5148 PetscValidType(mat,1); 5149 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5150 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5151 PetscCheck(mat->ops->transpose,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5152 PetscCheck(reuse != MAT_INPLACE_MATRIX || mat == *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 5153 PetscCheck(reuse != MAT_REUSE_MATRIX || mat != *B,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 5154 MatCheckPreallocated(mat,1); 5155 5156 PetscCall(PetscLogEventBegin(MAT_Transpose,mat,0,0,0)); 5157 PetscCall((*mat->ops->transpose)(mat,reuse,B)); 5158 PetscCall(PetscLogEventEnd(MAT_Transpose,mat,0,0,0)); 5159 if (B) PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5160 PetscFunctionReturn(0); 5161 } 5162 5163 /*@ 5164 MatIsTranspose - Test whether a matrix is another one's transpose, 5165 or its own, in which case it tests symmetry. 5166 5167 Collective on Mat 5168 5169 Input Parameters: 5170 + A - the matrix to test 5171 - B - the matrix to test against, this can equal the first parameter 5172 5173 Output Parameters: 5174 . flg - the result 5175 5176 Notes: 5177 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5178 has a running time of the order of the number of nonzeros; the parallel 5179 test involves parallel copies of the block-offdiagonal parts of the matrix. 5180 5181 Level: intermediate 5182 5183 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()` 5184 @*/ 5185 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5186 { 5187 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5188 5189 PetscFunctionBegin; 5190 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5191 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5192 PetscValidBoolPointer(flg,4); 5193 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f)); 5194 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g)); 5195 *flg = PETSC_FALSE; 5196 if (f && g) { 5197 PetscCheck(f == g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 5198 PetscCall((*f)(A,B,tol,flg)); 5199 } else { 5200 MatType mattype; 5201 5202 PetscCall(MatGetType(f ? B : A,&mattype)); 5203 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype); 5204 } 5205 PetscFunctionReturn(0); 5206 } 5207 5208 /*@ 5209 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 5210 5211 Collective on Mat 5212 5213 Input Parameters: 5214 + mat - the matrix to transpose and complex conjugate 5215 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 5216 5217 Output Parameter: 5218 . B - the Hermitian 5219 5220 Level: intermediate 5221 5222 .seealso: `MatTranspose()`, `MatMultTranspose()`, `MatMultTransposeAdd()`, `MatIsTranspose()`, `MatReuse` 5223 @*/ 5224 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 5225 { 5226 PetscFunctionBegin; 5227 PetscCall(MatTranspose(mat,reuse,B)); 5228 #if defined(PETSC_USE_COMPLEX) 5229 PetscCall(MatConjugate(*B)); 5230 #endif 5231 PetscFunctionReturn(0); 5232 } 5233 5234 /*@ 5235 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 5236 5237 Collective on Mat 5238 5239 Input Parameters: 5240 + A - the matrix to test 5241 - B - the matrix to test against, this can equal the first parameter 5242 5243 Output Parameters: 5244 . flg - the result 5245 5246 Notes: 5247 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 5248 has a running time of the order of the number of nonzeros; the parallel 5249 test involves parallel copies of the block-offdiagonal parts of the matrix. 5250 5251 Level: intermediate 5252 5253 .seealso: `MatTranspose()`, `MatIsSymmetric()`, `MatIsHermitian()`, `MatIsTranspose()` 5254 @*/ 5255 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 5256 { 5257 PetscErrorCode (*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 5258 5259 PetscFunctionBegin; 5260 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5261 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5262 PetscValidBoolPointer(flg,4); 5263 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f)); 5264 PetscCall(PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g)); 5265 if (f && g) { 5266 PetscCheck(f != g,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 5267 PetscCall((*f)(A,B,tol,flg)); 5268 } 5269 PetscFunctionReturn(0); 5270 } 5271 5272 /*@ 5273 MatPermute - Creates a new matrix with rows and columns permuted from the 5274 original. 5275 5276 Collective on Mat 5277 5278 Input Parameters: 5279 + mat - the matrix to permute 5280 . row - row permutation, each processor supplies only the permutation for its rows 5281 - col - column permutation, each processor supplies only the permutation for its columns 5282 5283 Output Parameters: 5284 . B - the permuted matrix 5285 5286 Level: advanced 5287 5288 Note: 5289 The index sets map from row/col of permuted matrix to row/col of original matrix. 5290 The index sets should be on the same communicator as Mat and have the same local sizes. 5291 5292 Developer Note: 5293 If you want to implement MatPermute for a matrix type, and your approach doesn't 5294 exploit the fact that row and col are permutations, consider implementing the 5295 more general MatCreateSubMatrix() instead. 5296 5297 .seealso: `MatGetOrdering()`, `ISAllGather()` 5298 5299 @*/ 5300 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 5301 { 5302 PetscFunctionBegin; 5303 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5304 PetscValidType(mat,1); 5305 PetscValidHeaderSpecific(row,IS_CLASSID,2); 5306 PetscValidHeaderSpecific(col,IS_CLASSID,3); 5307 PetscValidPointer(B,4); 5308 PetscCheckSameComm(mat,1,row,2); 5309 if (row != col) PetscCheckSameComm(row,2,col,3); 5310 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5311 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5312 PetscCheck(mat->ops->permute || mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 5313 MatCheckPreallocated(mat,1); 5314 5315 if (mat->ops->permute) { 5316 PetscCall((*mat->ops->permute)(mat,row,col,B)); 5317 PetscCall(PetscObjectStateIncrease((PetscObject)*B)); 5318 } else { 5319 PetscCall(MatCreateSubMatrix(mat, row, col, MAT_INITIAL_MATRIX, B)); 5320 } 5321 PetscFunctionReturn(0); 5322 } 5323 5324 /*@ 5325 MatEqual - Compares two matrices. 5326 5327 Collective on Mat 5328 5329 Input Parameters: 5330 + A - the first matrix 5331 - B - the second matrix 5332 5333 Output Parameter: 5334 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5335 5336 Level: intermediate 5337 5338 @*/ 5339 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5340 { 5341 PetscFunctionBegin; 5342 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5343 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5344 PetscValidType(A,1); 5345 PetscValidType(B,2); 5346 PetscValidBoolPointer(flg,3); 5347 PetscCheckSameComm(A,1,B,2); 5348 MatCheckPreallocated(A,1); 5349 MatCheckPreallocated(B,2); 5350 PetscCheck(A->assembled,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5351 PetscCheck(B->assembled,PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5352 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); 5353 if (A->ops->equal && A->ops->equal == B->ops->equal) { 5354 PetscCall((*A->ops->equal)(A,B,flg)); 5355 } else { 5356 PetscCall(MatMultEqual(A,B,10,flg)); 5357 } 5358 PetscFunctionReturn(0); 5359 } 5360 5361 /*@ 5362 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5363 matrices that are stored as vectors. Either of the two scaling 5364 matrices can be NULL. 5365 5366 Collective on Mat 5367 5368 Input Parameters: 5369 + mat - the matrix to be scaled 5370 . l - the left scaling vector (or NULL) 5371 - r - the right scaling vector (or NULL) 5372 5373 Notes: 5374 MatDiagonalScale() computes A = LAR, where 5375 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5376 The L scales the rows of the matrix, the R scales the columns of the matrix. 5377 5378 Level: intermediate 5379 5380 .seealso: `MatScale()`, `MatShift()`, `MatDiagonalSet()` 5381 @*/ 5382 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5383 { 5384 PetscFunctionBegin; 5385 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5386 PetscValidType(mat,1); 5387 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5388 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5389 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5390 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5391 MatCheckPreallocated(mat,1); 5392 if (!l && !r) PetscFunctionReturn(0); 5393 5394 PetscCheck(mat->ops->diagonalscale,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5395 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5396 PetscCall((*mat->ops->diagonalscale)(mat,l,r)); 5397 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5398 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5399 if (l != r && mat->symmetric) mat->symmetric = PETSC_FALSE; 5400 PetscFunctionReturn(0); 5401 } 5402 5403 /*@ 5404 MatScale - Scales all elements of a matrix by a given number. 5405 5406 Logically Collective on Mat 5407 5408 Input Parameters: 5409 + mat - the matrix to be scaled 5410 - a - the scaling value 5411 5412 Output Parameter: 5413 . mat - the scaled matrix 5414 5415 Level: intermediate 5416 5417 .seealso: `MatDiagonalScale()` 5418 @*/ 5419 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5420 { 5421 PetscFunctionBegin; 5422 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5423 PetscValidType(mat,1); 5424 PetscCheck(a == (PetscScalar)1.0 || mat->ops->scale,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5425 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5426 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5427 PetscValidLogicalCollectiveScalar(mat,a,2); 5428 MatCheckPreallocated(mat,1); 5429 5430 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 5431 if (a != (PetscScalar)1.0) { 5432 PetscCall((*mat->ops->scale)(mat,a)); 5433 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5434 } 5435 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 5436 PetscFunctionReturn(0); 5437 } 5438 5439 /*@ 5440 MatNorm - Calculates various norms of a matrix. 5441 5442 Collective on Mat 5443 5444 Input Parameters: 5445 + mat - the matrix 5446 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5447 5448 Output Parameter: 5449 . nrm - the resulting norm 5450 5451 Level: intermediate 5452 5453 @*/ 5454 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5455 { 5456 PetscFunctionBegin; 5457 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5458 PetscValidType(mat,1); 5459 PetscValidRealPointer(nrm,3); 5460 5461 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5462 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5463 PetscCheck(mat->ops->norm,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5464 MatCheckPreallocated(mat,1); 5465 5466 PetscCall((*mat->ops->norm)(mat,type,nrm)); 5467 PetscFunctionReturn(0); 5468 } 5469 5470 /* 5471 This variable is used to prevent counting of MatAssemblyBegin() that 5472 are called from within a MatAssemblyEnd(). 5473 */ 5474 static PetscInt MatAssemblyEnd_InUse = 0; 5475 /*@ 5476 MatAssemblyBegin - Begins assembling the matrix. This routine should 5477 be called after completing all calls to MatSetValues(). 5478 5479 Collective on Mat 5480 5481 Input Parameters: 5482 + mat - the matrix 5483 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 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 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5493 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 5494 a global collective operation requring all processes that share the matrix. 5495 5496 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5497 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5498 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5499 5500 Level: beginner 5501 5502 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssembled()` 5503 @*/ 5504 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5505 { 5506 PetscFunctionBegin; 5507 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5508 PetscValidType(mat,1); 5509 MatCheckPreallocated(mat,1); 5510 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5511 if (mat->assembled) { 5512 mat->was_assembled = PETSC_TRUE; 5513 mat->assembled = PETSC_FALSE; 5514 } 5515 5516 if (!MatAssemblyEnd_InUse) { 5517 PetscCall(PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0)); 5518 if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5519 PetscCall(PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0)); 5520 } else if (mat->ops->assemblybegin) PetscCall((*mat->ops->assemblybegin)(mat,type)); 5521 PetscFunctionReturn(0); 5522 } 5523 5524 /*@ 5525 MatAssembled - Indicates if a matrix has been assembled and is ready for 5526 use; for example, in matrix-vector product. 5527 5528 Not Collective 5529 5530 Input Parameter: 5531 . mat - the matrix 5532 5533 Output Parameter: 5534 . assembled - PETSC_TRUE or PETSC_FALSE 5535 5536 Level: advanced 5537 5538 .seealso: `MatAssemblyEnd()`, `MatSetValues()`, `MatAssemblyBegin()` 5539 @*/ 5540 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5541 { 5542 PetscFunctionBegin; 5543 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5544 PetscValidBoolPointer(assembled,2); 5545 *assembled = mat->assembled; 5546 PetscFunctionReturn(0); 5547 } 5548 5549 /*@ 5550 MatAssemblyEnd - Completes assembling the matrix. This routine should 5551 be called after MatAssemblyBegin(). 5552 5553 Collective on Mat 5554 5555 Input Parameters: 5556 + mat - the matrix 5557 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5558 5559 Options Database Keys: 5560 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5561 . -mat_view ::ascii_info_detail - Prints more detailed info 5562 . -mat_view - Prints matrix in ASCII format 5563 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5564 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5565 . -display <name> - Sets display name (default is host) 5566 . -draw_pause <sec> - Sets number of seconds to pause after display 5567 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab) 5568 . -viewer_socket_machine <machine> - Machine to use for socket 5569 . -viewer_socket_port <port> - Port number to use for socket 5570 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5571 5572 Notes: 5573 MatSetValues() generally caches the values. The matrix is ready to 5574 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5575 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5576 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5577 using the matrix. 5578 5579 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5580 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5581 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5582 5583 Level: beginner 5584 5585 .seealso: `MatAssemblyBegin()`, `MatSetValues()`, `PetscDrawOpenX()`, `PetscDrawCreate()`, `MatView()`, `MatAssembled()`, `PetscViewerSocketOpen()` 5586 @*/ 5587 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5588 { 5589 static PetscInt inassm = 0; 5590 PetscBool flg = PETSC_FALSE; 5591 5592 PetscFunctionBegin; 5593 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5594 PetscValidType(mat,1); 5595 5596 inassm++; 5597 MatAssemblyEnd_InUse++; 5598 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5599 PetscCall(PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0)); 5600 if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5601 PetscCall(PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0)); 5602 } else if (mat->ops->assemblyend) PetscCall((*mat->ops->assemblyend)(mat,type)); 5603 5604 /* Flush assembly is not a true assembly */ 5605 if (type != MAT_FLUSH_ASSEMBLY) { 5606 mat->num_ass++; 5607 mat->assembled = PETSC_TRUE; 5608 mat->ass_nonzerostate = mat->nonzerostate; 5609 } 5610 5611 mat->insertmode = NOT_SET_VALUES; 5612 MatAssemblyEnd_InUse--; 5613 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5614 if (!mat->symmetric_eternal) { 5615 mat->symmetric_set = PETSC_FALSE; 5616 mat->hermitian_set = PETSC_FALSE; 5617 mat->structurally_symmetric_set = PETSC_FALSE; 5618 } 5619 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5620 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 5621 5622 if (mat->checksymmetryonassembly) { 5623 PetscCall(MatIsSymmetric(mat,mat->checksymmetrytol,&flg)); 5624 if (flg) { 5625 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5626 } else { 5627 PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol)); 5628 } 5629 } 5630 if (mat->nullsp && mat->checknullspaceonassembly) { 5631 PetscCall(MatNullSpaceTest(mat->nullsp,mat,NULL)); 5632 } 5633 } 5634 inassm--; 5635 PetscFunctionReturn(0); 5636 } 5637 5638 /*@ 5639 MatSetOption - Sets a parameter option for a matrix. Some options 5640 may be specific to certain storage formats. Some options 5641 determine how values will be inserted (or added). Sorted, 5642 row-oriented input will generally assemble the fastest. The default 5643 is row-oriented. 5644 5645 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5646 5647 Input Parameters: 5648 + mat - the matrix 5649 . option - the option, one of those listed below (and possibly others), 5650 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5651 5652 Options Describing Matrix Structure: 5653 + MAT_SPD - symmetric positive definite 5654 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5655 . MAT_HERMITIAN - transpose is the complex conjugation 5656 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5657 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5658 you set to be kept with all future use of the matrix 5659 including after MatAssemblyBegin/End() which could 5660 potentially change the symmetry structure, i.e. you 5661 KNOW the matrix will ALWAYS have the property you set. 5662 Note that setting this flag alone implies nothing about whether the matrix is symmetric/Hermitian; 5663 the relevant flags must be set independently. 5664 5665 Options For Use with MatSetValues(): 5666 Insert a logically dense subblock, which can be 5667 . MAT_ROW_ORIENTED - row-oriented (default) 5668 5669 Note these options reflect the data you pass in with MatSetValues(); it has 5670 nothing to do with how the data is stored internally in the matrix 5671 data structure. 5672 5673 When (re)assembling a matrix, we can restrict the input for 5674 efficiency/debugging purposes. These options include 5675 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5676 . MAT_FORCE_DIAGONAL_ENTRIES - forces diagonal entries to be allocated 5677 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5678 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5679 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5680 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5681 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5682 performance for very large process counts. 5683 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5684 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5685 functions, instead sending only neighbor messages. 5686 5687 Notes: 5688 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5689 5690 Some options are relevant only for particular matrix types and 5691 are thus ignored by others. Other options are not supported by 5692 certain matrix types and will generate an error message if set. 5693 5694 If using a Fortran 77 module to compute a matrix, one may need to 5695 use the column-oriented option (or convert to the row-oriented 5696 format). 5697 5698 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5699 that would generate a new entry in the nonzero structure is instead 5700 ignored. Thus, if memory has not alredy been allocated for this particular 5701 data, then the insertion is ignored. For dense matrices, in which 5702 the entire array is allocated, no entries are ever ignored. 5703 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5704 5705 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5706 that would generate a new entry in the nonzero structure instead produces 5707 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 5708 5709 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5710 that would generate a new entry that has not been preallocated will 5711 instead produce an error. (Currently supported for AIJ and BAIJ formats 5712 only.) This is a useful flag when debugging matrix memory preallocation. 5713 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5714 5715 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5716 other processors should be dropped, rather than stashed. 5717 This is useful if you know that the "owning" processor is also 5718 always generating the correct matrix entries, so that PETSc need 5719 not transfer duplicate entries generated on another processor. 5720 5721 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5722 searches during matrix assembly. When this flag is set, the hash table 5723 is created during the first Matrix Assembly. This hash table is 5724 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5725 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5726 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5727 supported by MATMPIBAIJ format only. 5728 5729 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5730 are kept in the nonzero structure 5731 5732 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5733 a zero location in the matrix 5734 5735 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5736 5737 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5738 zero row routines and thus improves performance for very large process counts. 5739 5740 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5741 part of the matrix (since they should match the upper triangular part). 5742 5743 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5744 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5745 with finite difference schemes with non-periodic boundary conditions. 5746 5747 Level: intermediate 5748 5749 .seealso: `MatOption`, `Mat` 5750 5751 @*/ 5752 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5753 { 5754 PetscFunctionBegin; 5755 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5756 if (op > 0) { 5757 PetscValidLogicalCollectiveEnum(mat,op,2); 5758 PetscValidLogicalCollectiveBool(mat,flg,3); 5759 } 5760 5761 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); 5762 5763 switch (op) { 5764 case MAT_FORCE_DIAGONAL_ENTRIES: 5765 mat->force_diagonals = flg; 5766 PetscFunctionReturn(0); 5767 case MAT_NO_OFF_PROC_ENTRIES: 5768 mat->nooffprocentries = flg; 5769 PetscFunctionReturn(0); 5770 case MAT_SUBSET_OFF_PROC_ENTRIES: 5771 mat->assembly_subset = flg; 5772 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5773 #if !defined(PETSC_HAVE_MPIUNI) 5774 PetscCall(MatStashScatterDestroy_BTS(&mat->stash)); 5775 #endif 5776 mat->stash.first_assembly_done = PETSC_FALSE; 5777 } 5778 PetscFunctionReturn(0); 5779 case MAT_NO_OFF_PROC_ZERO_ROWS: 5780 mat->nooffproczerorows = flg; 5781 PetscFunctionReturn(0); 5782 case MAT_SPD: 5783 mat->spd_set = PETSC_TRUE; 5784 mat->spd = flg; 5785 if (flg) { 5786 mat->symmetric = PETSC_TRUE; 5787 mat->structurally_symmetric = PETSC_TRUE; 5788 mat->symmetric_set = PETSC_TRUE; 5789 mat->structurally_symmetric_set = PETSC_TRUE; 5790 } 5791 break; 5792 case MAT_SYMMETRIC: 5793 mat->symmetric = flg; 5794 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5795 mat->symmetric_set = PETSC_TRUE; 5796 mat->structurally_symmetric_set = flg; 5797 #if !defined(PETSC_USE_COMPLEX) 5798 mat->hermitian = flg; 5799 mat->hermitian_set = PETSC_TRUE; 5800 #endif 5801 break; 5802 case MAT_HERMITIAN: 5803 mat->hermitian = flg; 5804 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5805 mat->hermitian_set = PETSC_TRUE; 5806 mat->structurally_symmetric_set = flg; 5807 #if !defined(PETSC_USE_COMPLEX) 5808 mat->symmetric = flg; 5809 mat->symmetric_set = PETSC_TRUE; 5810 #endif 5811 break; 5812 case MAT_STRUCTURALLY_SYMMETRIC: 5813 mat->structurally_symmetric = flg; 5814 mat->structurally_symmetric_set = PETSC_TRUE; 5815 break; 5816 case MAT_SYMMETRY_ETERNAL: 5817 mat->symmetric_eternal = flg; 5818 break; 5819 case MAT_STRUCTURE_ONLY: 5820 mat->structure_only = flg; 5821 break; 5822 case MAT_SORTED_FULL: 5823 mat->sortedfull = flg; 5824 break; 5825 default: 5826 break; 5827 } 5828 if (mat->ops->setoption) PetscCall((*mat->ops->setoption)(mat,op,flg)); 5829 PetscFunctionReturn(0); 5830 } 5831 5832 /*@ 5833 MatGetOption - Gets a parameter option that has been set for a matrix. 5834 5835 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5836 5837 Input Parameters: 5838 + mat - the matrix 5839 - option - the option, this only responds to certain options, check the code for which ones 5840 5841 Output Parameter: 5842 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5843 5844 Notes: 5845 Can only be called after MatSetSizes() and MatSetType() have been set. 5846 5847 Level: intermediate 5848 5849 .seealso: `MatOption`, `MatSetOption()` 5850 5851 @*/ 5852 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5853 { 5854 PetscFunctionBegin; 5855 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5856 PetscValidType(mat,1); 5857 5858 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); 5859 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()"); 5860 5861 switch (op) { 5862 case MAT_NO_OFF_PROC_ENTRIES: 5863 *flg = mat->nooffprocentries; 5864 break; 5865 case MAT_NO_OFF_PROC_ZERO_ROWS: 5866 *flg = mat->nooffproczerorows; 5867 break; 5868 case MAT_SYMMETRIC: 5869 *flg = mat->symmetric; 5870 break; 5871 case MAT_HERMITIAN: 5872 *flg = mat->hermitian; 5873 break; 5874 case MAT_STRUCTURALLY_SYMMETRIC: 5875 *flg = mat->structurally_symmetric; 5876 break; 5877 case MAT_SYMMETRY_ETERNAL: 5878 *flg = mat->symmetric_eternal; 5879 break; 5880 case MAT_SPD: 5881 *flg = mat->spd; 5882 break; 5883 default: 5884 break; 5885 } 5886 PetscFunctionReturn(0); 5887 } 5888 5889 /*@ 5890 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5891 this routine retains the old nonzero structure. 5892 5893 Logically Collective on Mat 5894 5895 Input Parameters: 5896 . mat - the matrix 5897 5898 Level: intermediate 5899 5900 Notes: 5901 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. 5902 See the Performance chapter of the users manual for information on preallocating matrices. 5903 5904 .seealso: `MatZeroRows()` 5905 @*/ 5906 PetscErrorCode MatZeroEntries(Mat mat) 5907 { 5908 PetscFunctionBegin; 5909 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5910 PetscValidType(mat,1); 5911 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5912 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"); 5913 PetscCheck(mat->ops->zeroentries,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5914 MatCheckPreallocated(mat,1); 5915 5916 PetscCall(PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0)); 5917 PetscCall((*mat->ops->zeroentries)(mat)); 5918 PetscCall(PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0)); 5919 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5920 PetscFunctionReturn(0); 5921 } 5922 5923 /*@ 5924 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5925 of a set of rows and columns of a matrix. 5926 5927 Collective on Mat 5928 5929 Input Parameters: 5930 + mat - the matrix 5931 . numRows - the number of rows to remove 5932 . rows - the global row indices 5933 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5934 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5935 - b - optional vector of right hand side, that will be adjusted by provided solution 5936 5937 Notes: 5938 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5939 5940 The user can set a value in the diagonal entry (or for the AIJ and 5941 row formats can optionally remove the main diagonal entry from the 5942 nonzero structure as well, by passing 0.0 as the final argument). 5943 5944 For the parallel case, all processes that share the matrix (i.e., 5945 those in the communicator used for matrix creation) MUST call this 5946 routine, regardless of whether any rows being zeroed are owned by 5947 them. 5948 5949 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5950 list only rows local to itself). 5951 5952 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5953 5954 Level: intermediate 5955 5956 .seealso: `MatZeroRowsIS()`, `MatZeroRows()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 5957 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 5958 @*/ 5959 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5960 { 5961 PetscFunctionBegin; 5962 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5963 PetscValidType(mat,1); 5964 if (numRows) PetscValidIntPointer(rows,3); 5965 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5966 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5967 PetscCheck(mat->ops->zerorowscolumns,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5968 MatCheckPreallocated(mat,1); 5969 5970 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b)); 5971 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 5972 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 5973 PetscFunctionReturn(0); 5974 } 5975 5976 /*@ 5977 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5978 of a set of rows and columns of a matrix. 5979 5980 Collective on Mat 5981 5982 Input Parameters: 5983 + mat - the matrix 5984 . is - the rows to zero 5985 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5986 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5987 - b - optional vector of right hand side, that will be adjusted by provided solution 5988 5989 Notes: 5990 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5991 5992 The user can set a value in the diagonal entry (or for the AIJ and 5993 row formats can optionally remove the main diagonal entry from the 5994 nonzero structure as well, by passing 0.0 as the final argument). 5995 5996 For the parallel case, all processes that share the matrix (i.e., 5997 those in the communicator used for matrix creation) MUST call this 5998 routine, regardless of whether any rows being zeroed are owned by 5999 them. 6000 6001 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6002 list only rows local to itself). 6003 6004 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 6005 6006 Level: intermediate 6007 6008 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6009 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRows()`, `MatZeroRowsColumnsStencil()` 6010 @*/ 6011 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6012 { 6013 PetscInt numRows; 6014 const PetscInt *rows; 6015 6016 PetscFunctionBegin; 6017 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6018 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6019 PetscValidType(mat,1); 6020 PetscValidType(is,2); 6021 PetscCall(ISGetLocalSize(is,&numRows)); 6022 PetscCall(ISGetIndices(is,&rows)); 6023 PetscCall(MatZeroRowsColumns(mat,numRows,rows,diag,x,b)); 6024 PetscCall(ISRestoreIndices(is,&rows)); 6025 PetscFunctionReturn(0); 6026 } 6027 6028 /*@ 6029 MatZeroRows - Zeros all entries (except possibly the main diagonal) 6030 of a set of rows of a matrix. 6031 6032 Collective on Mat 6033 6034 Input Parameters: 6035 + mat - the matrix 6036 . numRows - the number of rows to remove 6037 . rows - the global row indices 6038 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6039 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6040 - b - optional vector of right hand side, that will be adjusted by provided solution 6041 6042 Notes: 6043 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6044 but does not release memory. For the dense and block diagonal 6045 formats this does not alter the nonzero structure. 6046 6047 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6048 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6049 merely zeroed. 6050 6051 The user can set a value in the diagonal entry (or for the AIJ and 6052 row formats can optionally remove the main diagonal entry from the 6053 nonzero structure as well, by passing 0.0 as the final argument). 6054 6055 For the parallel case, all processes that share the matrix (i.e., 6056 those in the communicator used for matrix creation) MUST call this 6057 routine, regardless of whether any rows being zeroed are owned by 6058 them. 6059 6060 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6061 list only rows local to itself). 6062 6063 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6064 owns that are to be zeroed. This saves a global synchronization in the implementation. 6065 6066 Level: intermediate 6067 6068 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6069 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6070 @*/ 6071 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6072 { 6073 PetscFunctionBegin; 6074 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6075 PetscValidType(mat,1); 6076 if (numRows) PetscValidIntPointer(rows,3); 6077 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6078 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6079 PetscCheck(mat->ops->zerorows,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6080 MatCheckPreallocated(mat,1); 6081 6082 PetscCall((*mat->ops->zerorows)(mat,numRows,rows,diag,x,b)); 6083 PetscCall(MatViewFromOptions(mat,NULL,"-mat_view")); 6084 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6085 PetscFunctionReturn(0); 6086 } 6087 6088 /*@ 6089 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 6090 of a set of rows of a matrix. 6091 6092 Collective on Mat 6093 6094 Input Parameters: 6095 + mat - the matrix 6096 . is - index set of rows to remove (if NULL then no row is removed) 6097 . diag - value put in all diagonals of eliminated rows 6098 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6099 - b - optional vector of right hand side, that will be adjusted by provided solution 6100 6101 Notes: 6102 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6103 but does not release memory. For the dense and block diagonal 6104 formats this does not alter the nonzero structure. 6105 6106 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6107 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6108 merely zeroed. 6109 6110 The user can set a value in the diagonal entry (or for the AIJ and 6111 row formats can optionally remove the main diagonal entry from the 6112 nonzero structure as well, by passing 0.0 as the final argument). 6113 6114 For the parallel case, all processes that share the matrix (i.e., 6115 those in the communicator used for matrix creation) MUST call this 6116 routine, regardless of whether any rows being zeroed are owned by 6117 them. 6118 6119 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6120 list only rows local to itself). 6121 6122 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6123 owns that are to be zeroed. This saves a global synchronization in the implementation. 6124 6125 Level: intermediate 6126 6127 .seealso: `MatZeroRows()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6128 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6129 @*/ 6130 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6131 { 6132 PetscInt numRows = 0; 6133 const PetscInt *rows = NULL; 6134 6135 PetscFunctionBegin; 6136 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6137 PetscValidType(mat,1); 6138 if (is) { 6139 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6140 PetscCall(ISGetLocalSize(is,&numRows)); 6141 PetscCall(ISGetIndices(is,&rows)); 6142 } 6143 PetscCall(MatZeroRows(mat,numRows,rows,diag,x,b)); 6144 if (is) { 6145 PetscCall(ISRestoreIndices(is,&rows)); 6146 } 6147 PetscFunctionReturn(0); 6148 } 6149 6150 /*@ 6151 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 6152 of a set of rows of a matrix. These rows must be local to the process. 6153 6154 Collective on Mat 6155 6156 Input Parameters: 6157 + mat - the matrix 6158 . numRows - the number of rows to remove 6159 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6160 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6161 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6162 - b - optional vector of right hand side, that will be adjusted by provided solution 6163 6164 Notes: 6165 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6166 but does not release memory. For the dense and block diagonal 6167 formats this does not alter the nonzero structure. 6168 6169 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6170 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6171 merely zeroed. 6172 6173 The user can set a value in the diagonal entry (or for the AIJ and 6174 row formats can optionally remove the main diagonal entry from the 6175 nonzero structure as well, by passing 0.0 as the final argument). 6176 6177 For the parallel case, all processes that share the matrix (i.e., 6178 those in the communicator used for matrix creation) MUST call this 6179 routine, regardless of whether any rows being zeroed are owned by 6180 them. 6181 6182 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6183 list only rows local to itself). 6184 6185 The grid coordinates are across the entire grid, not just the local portion 6186 6187 In Fortran idxm and idxn should be declared as 6188 $ MatStencil idxm(4,m) 6189 and the values inserted using 6190 $ idxm(MatStencil_i,1) = i 6191 $ idxm(MatStencil_j,1) = j 6192 $ idxm(MatStencil_k,1) = k 6193 $ idxm(MatStencil_c,1) = c 6194 etc 6195 6196 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6197 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6198 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6199 DM_BOUNDARY_PERIODIC boundary type. 6200 6201 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 6202 a single value per point) you can skip filling those indices. 6203 6204 Level: intermediate 6205 6206 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsl()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6207 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6208 @*/ 6209 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6210 { 6211 PetscInt dim = mat->stencil.dim; 6212 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6213 PetscInt *dims = mat->stencil.dims+1; 6214 PetscInt *starts = mat->stencil.starts; 6215 PetscInt *dxm = (PetscInt*) rows; 6216 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6217 6218 PetscFunctionBegin; 6219 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6220 PetscValidType(mat,1); 6221 if (numRows) PetscValidPointer(rows,3); 6222 6223 PetscCall(PetscMalloc1(numRows, &jdxm)); 6224 for (i = 0; i < numRows; ++i) { 6225 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6226 for (j = 0; j < 3-sdim; ++j) dxm++; 6227 /* Local index in X dir */ 6228 tmp = *dxm++ - starts[0]; 6229 /* Loop over remaining dimensions */ 6230 for (j = 0; j < dim-1; ++j) { 6231 /* If nonlocal, set index to be negative */ 6232 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6233 /* Update local index */ 6234 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6235 } 6236 /* Skip component slot if necessary */ 6237 if (mat->stencil.noc) dxm++; 6238 /* Local row number */ 6239 if (tmp >= 0) { 6240 jdxm[numNewRows++] = tmp; 6241 } 6242 } 6243 PetscCall(MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b)); 6244 PetscCall(PetscFree(jdxm)); 6245 PetscFunctionReturn(0); 6246 } 6247 6248 /*@ 6249 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 6250 of a set of rows and columns of a matrix. 6251 6252 Collective on Mat 6253 6254 Input Parameters: 6255 + mat - the matrix 6256 . numRows - the number of rows/columns to remove 6257 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 6258 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 6259 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6260 - b - optional vector of right hand side, that will be adjusted by provided solution 6261 6262 Notes: 6263 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6264 but does not release memory. For the dense and block diagonal 6265 formats this does not alter the nonzero structure. 6266 6267 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6268 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6269 merely zeroed. 6270 6271 The user can set a value in the diagonal entry (or for the AIJ and 6272 row formats can optionally remove the main diagonal entry from the 6273 nonzero structure as well, by passing 0.0 as the final argument). 6274 6275 For the parallel case, all processes that share the matrix (i.e., 6276 those in the communicator used for matrix creation) MUST call this 6277 routine, regardless of whether any rows being zeroed are owned by 6278 them. 6279 6280 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6281 list only rows local to itself, but the row/column numbers are given in local numbering). 6282 6283 The grid coordinates are across the entire grid, not just the local portion 6284 6285 In Fortran idxm and idxn should be declared as 6286 $ MatStencil idxm(4,m) 6287 and the values inserted using 6288 $ idxm(MatStencil_i,1) = i 6289 $ idxm(MatStencil_j,1) = j 6290 $ idxm(MatStencil_k,1) = k 6291 $ idxm(MatStencil_c,1) = c 6292 etc 6293 6294 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6295 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6296 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6297 DM_BOUNDARY_PERIODIC boundary type. 6298 6299 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 6300 a single value per point) you can skip filling those indices. 6301 6302 Level: intermediate 6303 6304 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6305 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRows()` 6306 @*/ 6307 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6308 { 6309 PetscInt dim = mat->stencil.dim; 6310 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6311 PetscInt *dims = mat->stencil.dims+1; 6312 PetscInt *starts = mat->stencil.starts; 6313 PetscInt *dxm = (PetscInt*) rows; 6314 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6315 6316 PetscFunctionBegin; 6317 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6318 PetscValidType(mat,1); 6319 if (numRows) PetscValidPointer(rows,3); 6320 6321 PetscCall(PetscMalloc1(numRows, &jdxm)); 6322 for (i = 0; i < numRows; ++i) { 6323 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6324 for (j = 0; j < 3-sdim; ++j) dxm++; 6325 /* Local index in X dir */ 6326 tmp = *dxm++ - starts[0]; 6327 /* Loop over remaining dimensions */ 6328 for (j = 0; j < dim-1; ++j) { 6329 /* If nonlocal, set index to be negative */ 6330 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6331 /* Update local index */ 6332 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6333 } 6334 /* Skip component slot if necessary */ 6335 if (mat->stencil.noc) dxm++; 6336 /* Local row number */ 6337 if (tmp >= 0) { 6338 jdxm[numNewRows++] = tmp; 6339 } 6340 } 6341 PetscCall(MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b)); 6342 PetscCall(PetscFree(jdxm)); 6343 PetscFunctionReturn(0); 6344 } 6345 6346 /*@C 6347 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6348 of a set of rows of a matrix; using local numbering of rows. 6349 6350 Collective on Mat 6351 6352 Input Parameters: 6353 + mat - the matrix 6354 . numRows - the number of rows to remove 6355 . rows - the local row indices 6356 . diag - value put in all diagonals of eliminated rows 6357 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6358 - b - optional vector of right hand side, that will be adjusted by provided solution 6359 6360 Notes: 6361 Before calling MatZeroRowsLocal(), the user must first set the 6362 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6363 6364 For the AIJ matrix formats this removes the old nonzero structure, 6365 but does not release memory. For the dense and block diagonal 6366 formats this does not alter the nonzero structure. 6367 6368 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6369 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6370 merely zeroed. 6371 6372 The user can set a value in the diagonal entry (or for the AIJ and 6373 row formats can optionally remove the main diagonal entry from the 6374 nonzero structure as well, by passing 0.0 as the final argument). 6375 6376 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6377 owns that are to be zeroed. This saves a global synchronization in the implementation. 6378 6379 Level: intermediate 6380 6381 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRows()`, `MatSetOption()`, 6382 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6383 @*/ 6384 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6385 { 6386 PetscFunctionBegin; 6387 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6388 PetscValidType(mat,1); 6389 if (numRows) PetscValidIntPointer(rows,3); 6390 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6391 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6392 MatCheckPreallocated(mat,1); 6393 6394 if (mat->ops->zerorowslocal) { 6395 PetscCall((*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b)); 6396 } else { 6397 IS is, newis; 6398 const PetscInt *newRows; 6399 6400 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6401 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6402 PetscCall(ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis)); 6403 PetscCall(ISGetIndices(newis,&newRows)); 6404 PetscCall((*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b)); 6405 PetscCall(ISRestoreIndices(newis,&newRows)); 6406 PetscCall(ISDestroy(&newis)); 6407 PetscCall(ISDestroy(&is)); 6408 } 6409 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6410 PetscFunctionReturn(0); 6411 } 6412 6413 /*@ 6414 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6415 of a set of rows of a matrix; using local numbering of rows. 6416 6417 Collective on Mat 6418 6419 Input Parameters: 6420 + mat - the matrix 6421 . is - index set of rows to remove 6422 . diag - value put in all diagonals of eliminated rows 6423 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6424 - b - optional vector of right hand side, that will be adjusted by provided solution 6425 6426 Notes: 6427 Before calling MatZeroRowsLocalIS(), the user must first set the 6428 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6429 6430 For the AIJ matrix formats this removes the old nonzero structure, 6431 but does not release memory. For the dense and block diagonal 6432 formats this does not alter the nonzero structure. 6433 6434 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6435 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6436 merely zeroed. 6437 6438 The user can set a value in the diagonal entry (or for the AIJ and 6439 row formats can optionally remove the main diagonal entry from the 6440 nonzero structure as well, by passing 0.0 as the final argument). 6441 6442 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6443 owns that are to be zeroed. This saves a global synchronization in the implementation. 6444 6445 Level: intermediate 6446 6447 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRows()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6448 `MatZeroRowsColumnsLocal()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6449 @*/ 6450 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6451 { 6452 PetscInt numRows; 6453 const PetscInt *rows; 6454 6455 PetscFunctionBegin; 6456 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6457 PetscValidType(mat,1); 6458 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6459 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6460 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6461 MatCheckPreallocated(mat,1); 6462 6463 PetscCall(ISGetLocalSize(is,&numRows)); 6464 PetscCall(ISGetIndices(is,&rows)); 6465 PetscCall(MatZeroRowsLocal(mat,numRows,rows,diag,x,b)); 6466 PetscCall(ISRestoreIndices(is,&rows)); 6467 PetscFunctionReturn(0); 6468 } 6469 6470 /*@ 6471 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6472 of a set of rows and columns of a matrix; using local numbering of rows. 6473 6474 Collective on Mat 6475 6476 Input Parameters: 6477 + mat - the matrix 6478 . numRows - the number of rows to remove 6479 . rows - the global row indices 6480 . diag - value put in all diagonals of eliminated rows 6481 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6482 - b - optional vector of right hand side, that will be adjusted by provided solution 6483 6484 Notes: 6485 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6486 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6487 6488 The user can set a value in the diagonal entry (or for the AIJ and 6489 row formats can optionally remove the main diagonal entry from the 6490 nonzero structure as well, by passing 0.0 as the final argument). 6491 6492 Level: intermediate 6493 6494 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6495 `MatZeroRows()`, `MatZeroRowsColumnsLocalIS()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6496 @*/ 6497 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6498 { 6499 IS is, newis; 6500 const PetscInt *newRows; 6501 6502 PetscFunctionBegin; 6503 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6504 PetscValidType(mat,1); 6505 if (numRows) PetscValidIntPointer(rows,3); 6506 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6507 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6508 MatCheckPreallocated(mat,1); 6509 6510 PetscCheck(mat->cmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6511 PetscCall(ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is)); 6512 PetscCall(ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis)); 6513 PetscCall(ISGetIndices(newis,&newRows)); 6514 PetscCall((*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b)); 6515 PetscCall(ISRestoreIndices(newis,&newRows)); 6516 PetscCall(ISDestroy(&newis)); 6517 PetscCall(ISDestroy(&is)); 6518 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 6519 PetscFunctionReturn(0); 6520 } 6521 6522 /*@ 6523 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6524 of a set of rows and columns of a matrix; using local numbering of rows. 6525 6526 Collective on Mat 6527 6528 Input Parameters: 6529 + mat - the matrix 6530 . is - index set of rows to remove 6531 . diag - value put in all diagonals of eliminated rows 6532 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6533 - b - optional vector of right hand side, that will be adjusted by provided solution 6534 6535 Notes: 6536 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6537 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6538 6539 The user can set a value in the diagonal entry (or for the AIJ and 6540 row formats can optionally remove the main diagonal entry from the 6541 nonzero structure as well, by passing 0.0 as the final argument). 6542 6543 Level: intermediate 6544 6545 .seealso: `MatZeroRowsIS()`, `MatZeroRowsColumns()`, `MatZeroRowsLocalIS()`, `MatZeroRowsStencil()`, `MatZeroEntries()`, `MatZeroRowsLocal()`, `MatSetOption()`, 6546 `MatZeroRowsColumnsLocal()`, `MatZeroRows()`, `MatZeroRowsColumnsIS()`, `MatZeroRowsColumnsStencil()` 6547 @*/ 6548 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6549 { 6550 PetscInt numRows; 6551 const PetscInt *rows; 6552 6553 PetscFunctionBegin; 6554 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6555 PetscValidType(mat,1); 6556 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6557 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6558 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6559 MatCheckPreallocated(mat,1); 6560 6561 PetscCall(ISGetLocalSize(is,&numRows)); 6562 PetscCall(ISGetIndices(is,&rows)); 6563 PetscCall(MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b)); 6564 PetscCall(ISRestoreIndices(is,&rows)); 6565 PetscFunctionReturn(0); 6566 } 6567 6568 /*@C 6569 MatGetSize - Returns the numbers of rows and columns in a matrix. 6570 6571 Not Collective 6572 6573 Input Parameter: 6574 . mat - the matrix 6575 6576 Output Parameters: 6577 + m - the number of global rows 6578 - n - the number of global columns 6579 6580 Note: both output parameters can be NULL on input. 6581 6582 Level: beginner 6583 6584 .seealso: `MatGetLocalSize()` 6585 @*/ 6586 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6587 { 6588 PetscFunctionBegin; 6589 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6590 if (m) *m = mat->rmap->N; 6591 if (n) *n = mat->cmap->N; 6592 PetscFunctionReturn(0); 6593 } 6594 6595 /*@C 6596 MatGetLocalSize - For most matrix formats, excluding `MATELEMENTAL` and `MATSCALAPACK`, Returns the number of local rows and local columns 6597 of a matrix. For all matrices this is the local size of the left and right vectors as returned by MatCreateVecs(). 6598 6599 Not Collective 6600 6601 Input Parameter: 6602 . mat - the matrix 6603 6604 Output Parameters: 6605 + m - the number of local rows, use `NULL` to not obtain this value 6606 - n - the number of local columns, use `NULL` to not obtain this value 6607 6608 Level: beginner 6609 6610 .seealso: `MatGetSize()` 6611 @*/ 6612 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6613 { 6614 PetscFunctionBegin; 6615 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6616 if (m) PetscValidIntPointer(m,2); 6617 if (n) PetscValidIntPointer(n,3); 6618 if (m) *m = mat->rmap->n; 6619 if (n) *n = mat->cmap->n; 6620 PetscFunctionReturn(0); 6621 } 6622 6623 /*@C 6624 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies this matrix by that are owned by 6625 this processor. (The columns of the "diagonal block" for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6626 6627 Not Collective, unless matrix has not been allocated, then collective on Mat 6628 6629 Input Parameter: 6630 . mat - the matrix 6631 6632 Output Parameters: 6633 + m - the global index of the first local column, use `NULL` to not obtain this value 6634 - n - one more than the global index of the last local column, use `NULL` to not obtain this value 6635 6636 Level: developer 6637 6638 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6639 6640 @*/ 6641 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6642 { 6643 PetscFunctionBegin; 6644 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6645 PetscValidType(mat,1); 6646 if (m) PetscValidIntPointer(m,2); 6647 if (n) PetscValidIntPointer(n,3); 6648 MatCheckPreallocated(mat,1); 6649 if (m) *m = mat->cmap->rstart; 6650 if (n) *n = mat->cmap->rend; 6651 PetscFunctionReturn(0); 6652 } 6653 6654 /*@C 6655 MatGetOwnershipRange - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6656 this MPI rank. For all matrices it returns the range of matrix rows associated with rows of a vector that would contain the result of a matrix 6657 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6658 6659 Not Collective 6660 6661 Input Parameter: 6662 . mat - the matrix 6663 6664 Output Parameters: 6665 + m - the global index of the first local row, use `NULL` to not obtain this value 6666 - n - one more than the global index of the last local row, use `NULL` to not obtain this value 6667 6668 Note: 6669 This function requires that the matrix be preallocated. If you have not preallocated, consider using 6670 `PetscSplitOwnership`(`MPI_Comm` comm, `PetscInt` *n, `PetscInt` *N) 6671 and then `MPI_Scan()` to calculate prefix sums of the local sizes. 6672 6673 Level: beginner 6674 6675 .seealso: `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscSplitOwnership()`, `PetscSplitOwnershipBlock()`, 6676 `PetscLayout` 6677 6678 @*/ 6679 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6680 { 6681 PetscFunctionBegin; 6682 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6683 PetscValidType(mat,1); 6684 if (m) PetscValidIntPointer(m,2); 6685 if (n) PetscValidIntPointer(n,3); 6686 MatCheckPreallocated(mat,1); 6687 if (m) *m = mat->rmap->rstart; 6688 if (n) *n = mat->rmap->rend; 6689 PetscFunctionReturn(0); 6690 } 6691 6692 /*@C 6693 MatGetOwnershipRanges - For matrices that own values by row, excludes `MATELEMENTAL` and `MATSCALAPACK`, returns the range of matrix rows owned by 6694 each process. For all matrices it returns the ranges of matrix rows associated with rows of a vector that would contain the result of a matrix 6695 vector product with this matrix. See :any:`<sec_matlayout>` for details on matrix layouts 6696 6697 Not Collective, unless matrix has not been allocated, then collective on Mat 6698 6699 Input Parameters: 6700 . mat - the matrix 6701 6702 Output Parameters: 6703 . ranges - start of each processors portion plus one more than the total length at the end 6704 6705 Level: beginner 6706 6707 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscLayout` 6708 6709 @*/ 6710 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6711 { 6712 PetscFunctionBegin; 6713 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6714 PetscValidType(mat,1); 6715 MatCheckPreallocated(mat,1); 6716 PetscCall(PetscLayoutGetRanges(mat->rmap,ranges)); 6717 PetscFunctionReturn(0); 6718 } 6719 6720 /*@C 6721 MatGetOwnershipRangesColumn - Returns the ranges of matrix columns associated with rows of a vector one multiplies this vector by that are owned by 6722 each processor. (The columns of the "diagonal blocks", for most sparse matrix formats). See :any:`<sec_matlayout>` for details on matrix layouts. 6723 6724 Not Collective, unless matrix has not been allocated, then collective on Mat 6725 6726 Input Parameters: 6727 . mat - the matrix 6728 6729 Output Parameters: 6730 . ranges - start of each processors portion plus one more then the total length at the end 6731 6732 Level: beginner 6733 6734 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRanges()` 6735 6736 @*/ 6737 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6738 { 6739 PetscFunctionBegin; 6740 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6741 PetscValidType(mat,1); 6742 MatCheckPreallocated(mat,1); 6743 PetscCall(PetscLayoutGetRanges(mat->cmap,ranges)); 6744 PetscFunctionReturn(0); 6745 } 6746 6747 /*@C 6748 MatGetOwnershipIS - Get row and column ownership of a matrices' values as index sets. For most matrices, excluding `MATELEMENTAL` and `MATSCALAPACK`, this 6749 corresponds to values returned by `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`. For `MATELEMENTAL` and `MATSCALAPACK` the ownership 6750 is more complicated. See :any:`<sec_matlayout>` for details on matrix layouts. 6751 6752 Not Collective 6753 6754 Input Parameter: 6755 . A - matrix 6756 6757 Output Parameters: 6758 + rows - rows in which this process owns elements, , use `NULL` to not obtain this value 6759 - cols - columns in which this process owns elements, use `NULL` to not obtain this value 6760 6761 Level: intermediate 6762 6763 .seealso: `MatGetOwnershipRange()`, `MatGetOwnershipRangeColumn()`, `MatSetValues()`, ``MATELEMENTAL``, ``MATSCALAPACK`` 6764 @*/ 6765 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6766 { 6767 PetscErrorCode (*f)(Mat,IS*,IS*); 6768 6769 PetscFunctionBegin; 6770 MatCheckPreallocated(A,1); 6771 PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f)); 6772 if (f) { 6773 PetscCall((*f)(A,rows,cols)); 6774 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6775 if (rows) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows)); 6776 if (cols) PetscCall(ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols)); 6777 } 6778 PetscFunctionReturn(0); 6779 } 6780 6781 /*@C 6782 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6783 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6784 to complete the factorization. 6785 6786 Collective on Mat 6787 6788 Input Parameters: 6789 + mat - the matrix 6790 . row - row permutation 6791 . column - column permutation 6792 - info - structure containing 6793 $ levels - number of levels of fill. 6794 $ expected fill - as ratio of original fill. 6795 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6796 missing diagonal entries) 6797 6798 Output Parameters: 6799 . fact - new matrix that has been symbolically factored 6800 6801 Notes: 6802 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6803 6804 Most users should employ the simplified KSP interface for linear solvers 6805 instead of working directly with matrix algebra routines such as this. 6806 See, e.g., KSPCreate(). 6807 6808 Level: developer 6809 6810 .seealso: `MatLUFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 6811 `MatGetOrdering()`, `MatFactorInfo` 6812 6813 Note: this uses the definition of level of fill as in Y. Saad, 2003 6814 6815 Developer Note: fortran interface is not autogenerated as the f90 6816 interface definition cannot be generated correctly [due to MatFactorInfo] 6817 6818 References: 6819 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6820 @*/ 6821 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6822 { 6823 PetscFunctionBegin; 6824 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6825 PetscValidType(mat,2); 6826 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,3); 6827 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,4); 6828 PetscValidPointer(info,5); 6829 PetscValidPointer(fact,1); 6830 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %" PetscInt_FMT,(PetscInt)info->levels); 6831 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6832 if (!fact->ops->ilufactorsymbolic) { 6833 MatSolverType stype; 6834 PetscCall(MatFactorGetSolverType(fact,&stype)); 6835 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver type %s",((PetscObject)mat)->type_name,stype); 6836 } 6837 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6838 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6839 MatCheckPreallocated(mat,2); 6840 6841 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0)); 6842 PetscCall((fact->ops->ilufactorsymbolic)(fact,mat,row,col,info)); 6843 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0)); 6844 PetscFunctionReturn(0); 6845 } 6846 6847 /*@C 6848 MatICCFactorSymbolic - Performs symbolic incomplete 6849 Cholesky factorization for a symmetric matrix. Use 6850 MatCholeskyFactorNumeric() to complete the factorization. 6851 6852 Collective on Mat 6853 6854 Input Parameters: 6855 + mat - the matrix 6856 . perm - row and column permutation 6857 - info - structure containing 6858 $ levels - number of levels of fill. 6859 $ expected fill - as ratio of original fill. 6860 6861 Output Parameter: 6862 . fact - the factored matrix 6863 6864 Notes: 6865 Most users should employ the KSP interface for linear solvers 6866 instead of working directly with matrix algebra routines such as this. 6867 See, e.g., KSPCreate(). 6868 6869 Level: developer 6870 6871 .seealso: `MatCholeskyFactorNumeric()`, `MatCholeskyFactor()`, `MatFactorInfo` 6872 6873 Note: this uses the definition of level of fill as in Y. Saad, 2003 6874 6875 Developer Note: fortran interface is not autogenerated as the f90 6876 interface definition cannot be generated correctly [due to MatFactorInfo] 6877 6878 References: 6879 . * - Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6880 @*/ 6881 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6882 { 6883 PetscFunctionBegin; 6884 PetscValidHeaderSpecific(mat,MAT_CLASSID,2); 6885 PetscValidType(mat,2); 6886 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,3); 6887 PetscValidPointer(info,4); 6888 PetscValidPointer(fact,1); 6889 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6890 PetscCheck(info->levels >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %" PetscInt_FMT,(PetscInt) info->levels); 6891 PetscCheck(info->fill >= 1.0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6892 if (!(fact)->ops->iccfactorsymbolic) { 6893 MatSolverType stype; 6894 PetscCall(MatFactorGetSolverType(fact,&stype)); 6895 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver type %s",((PetscObject)mat)->type_name,stype); 6896 } 6897 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6898 MatCheckPreallocated(mat,2); 6899 6900 if (!fact->trivialsymbolic) PetscCall(PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6901 PetscCall((fact->ops->iccfactorsymbolic)(fact,mat,perm,info)); 6902 if (!fact->trivialsymbolic) PetscCall(PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0)); 6903 PetscFunctionReturn(0); 6904 } 6905 6906 /*@C 6907 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6908 points to an array of valid matrices, they may be reused to store the new 6909 submatrices. 6910 6911 Collective on Mat 6912 6913 Input Parameters: 6914 + mat - the matrix 6915 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6916 . irow, icol - index sets of rows and columns to extract 6917 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6918 6919 Output Parameter: 6920 . submat - the array of submatrices 6921 6922 Notes: 6923 MatCreateSubMatrices() can extract ONLY sequential submatrices 6924 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6925 to extract a parallel submatrix. 6926 6927 Some matrix types place restrictions on the row and column 6928 indices, such as that they be sorted or that they be equal to each other. 6929 6930 The index sets may not have duplicate entries. 6931 6932 When extracting submatrices from a parallel matrix, each processor can 6933 form a different submatrix by setting the rows and columns of its 6934 individual index sets according to the local submatrix desired. 6935 6936 When finished using the submatrices, the user should destroy 6937 them with MatDestroySubMatrices(). 6938 6939 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6940 original matrix has not changed from that last call to MatCreateSubMatrices(). 6941 6942 This routine creates the matrices in submat; you should NOT create them before 6943 calling it. It also allocates the array of matrix pointers submat. 6944 6945 For BAIJ matrices the index sets must respect the block structure, that is if they 6946 request one row/column in a block, they must request all rows/columns that are in 6947 that block. For example, if the block size is 2 you cannot request just row 0 and 6948 column 0. 6949 6950 Fortran Note: 6951 The Fortran interface is slightly different from that given below; it 6952 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6953 6954 Level: advanced 6955 6956 .seealso: `MatDestroySubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 6957 @*/ 6958 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6959 { 6960 PetscInt i; 6961 PetscBool eq; 6962 6963 PetscFunctionBegin; 6964 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6965 PetscValidType(mat,1); 6966 if (n) { 6967 PetscValidPointer(irow,3); 6968 for (i=0; i<n; i++) PetscValidHeaderSpecific(irow[i],IS_CLASSID,3); 6969 PetscValidPointer(icol,4); 6970 for (i=0; i<n; i++) PetscValidHeaderSpecific(icol[i],IS_CLASSID,4); 6971 } 6972 PetscValidPointer(submat,6); 6973 if (n && scall == MAT_REUSE_MATRIX) { 6974 PetscValidPointer(*submat,6); 6975 for (i=0; i<n; i++) PetscValidHeaderSpecific((*submat)[i],MAT_CLASSID,6); 6976 } 6977 PetscCheck(mat->ops->createsubmatrices,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6978 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6979 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6980 MatCheckPreallocated(mat,1); 6981 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 6982 PetscCall((*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat)); 6983 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 6984 for (i=0; i<n; i++) { 6985 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6986 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 6987 if (eq) { 6988 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 6989 } 6990 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6991 if (mat->boundtocpu && mat->bindingpropagates) { 6992 PetscCall(MatBindToCPU((*submat)[i],PETSC_TRUE)); 6993 PetscCall(MatSetBindingPropagates((*submat)[i],PETSC_TRUE)); 6994 } 6995 #endif 6996 } 6997 PetscFunctionReturn(0); 6998 } 6999 7000 /*@C 7001 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 7002 7003 Collective on Mat 7004 7005 Input Parameters: 7006 + mat - the matrix 7007 . n - the number of submatrixes to be extracted 7008 . irow, icol - index sets of rows and columns to extract 7009 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7010 7011 Output Parameter: 7012 . submat - the array of submatrices 7013 7014 Level: advanced 7015 7016 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatrix()`, `MatGetRow()`, `MatGetDiagonal()`, `MatReuse` 7017 @*/ 7018 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 7019 { 7020 PetscInt i; 7021 PetscBool eq; 7022 7023 PetscFunctionBegin; 7024 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7025 PetscValidType(mat,1); 7026 if (n) { 7027 PetscValidPointer(irow,3); 7028 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 7029 PetscValidPointer(icol,4); 7030 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 7031 } 7032 PetscValidPointer(submat,6); 7033 if (n && scall == MAT_REUSE_MATRIX) { 7034 PetscValidPointer(*submat,6); 7035 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 7036 } 7037 PetscCheck(mat->ops->createsubmatricesmpi,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7038 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7039 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7040 MatCheckPreallocated(mat,1); 7041 7042 PetscCall(PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0)); 7043 PetscCall((*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat)); 7044 PetscCall(PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0)); 7045 for (i=0; i<n; i++) { 7046 PetscCall(ISEqualUnsorted(irow[i],icol[i],&eq)); 7047 if (eq) { 7048 PetscCall(MatPropagateSymmetryOptions(mat,(*submat)[i])); 7049 } 7050 } 7051 PetscFunctionReturn(0); 7052 } 7053 7054 /*@C 7055 MatDestroyMatrices - Destroys an array of matrices. 7056 7057 Collective on Mat 7058 7059 Input Parameters: 7060 + n - the number of local matrices 7061 - mat - the matrices (note that this is a pointer to the array of matrices) 7062 7063 Level: advanced 7064 7065 Notes: 7066 Frees not only the matrices, but also the array that contains the matrices 7067 In Fortran will not free the array. 7068 7069 .seealso: `MatCreateSubMatrices()` `MatDestroySubMatrices()` 7070 @*/ 7071 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 7072 { 7073 PetscInt i; 7074 7075 PetscFunctionBegin; 7076 if (!*mat) PetscFunctionReturn(0); 7077 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7078 PetscValidPointer(mat,2); 7079 7080 for (i=0; i<n; i++) { 7081 PetscCall(MatDestroy(&(*mat)[i])); 7082 } 7083 7084 /* memory is allocated even if n = 0 */ 7085 PetscCall(PetscFree(*mat)); 7086 PetscFunctionReturn(0); 7087 } 7088 7089 /*@C 7090 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 7091 7092 Collective on Mat 7093 7094 Input Parameters: 7095 + n - the number of local matrices 7096 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 7097 sequence of MatCreateSubMatrices()) 7098 7099 Level: advanced 7100 7101 Notes: 7102 Frees not only the matrices, but also the array that contains the matrices 7103 In Fortran will not free the array. 7104 7105 .seealso: `MatCreateSubMatrices()` 7106 @*/ 7107 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 7108 { 7109 Mat mat0; 7110 7111 PetscFunctionBegin; 7112 if (!*mat) PetscFunctionReturn(0); 7113 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 7114 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %" PetscInt_FMT,n); 7115 PetscValidPointer(mat,2); 7116 7117 mat0 = (*mat)[0]; 7118 if (mat0 && mat0->ops->destroysubmatrices) { 7119 PetscCall((mat0->ops->destroysubmatrices)(n,mat)); 7120 } else { 7121 PetscCall(MatDestroyMatrices(n,mat)); 7122 } 7123 PetscFunctionReturn(0); 7124 } 7125 7126 /*@C 7127 MatGetSeqNonzeroStructure - Extracts the nonzero structure from a matrix and stores it, in its entirety, on each process 7128 7129 Collective on Mat 7130 7131 Input Parameters: 7132 . mat - the matrix 7133 7134 Output Parameter: 7135 . matstruct - the sequential matrix with the nonzero structure of mat 7136 7137 Level: intermediate 7138 7139 .seealso: `MatDestroySeqNonzeroStructure()`, `MatCreateSubMatrices()`, `MatDestroyMatrices()` 7140 @*/ 7141 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 7142 { 7143 PetscFunctionBegin; 7144 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7145 PetscValidPointer(matstruct,2); 7146 7147 PetscValidType(mat,1); 7148 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7149 MatCheckPreallocated(mat,1); 7150 7151 PetscCheck(mat->ops->getseqnonzerostructure,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)mat)->type_name); 7152 PetscCall(PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7153 PetscCall((*mat->ops->getseqnonzerostructure)(mat,matstruct)); 7154 PetscCall(PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0)); 7155 PetscFunctionReturn(0); 7156 } 7157 7158 /*@C 7159 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 7160 7161 Collective on Mat 7162 7163 Input Parameters: 7164 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 7165 sequence of MatGetSequentialNonzeroStructure()) 7166 7167 Level: advanced 7168 7169 Notes: 7170 Frees not only the matrices, but also the array that contains the matrices 7171 7172 .seealso: `MatGetSeqNonzeroStructure()` 7173 @*/ 7174 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 7175 { 7176 PetscFunctionBegin; 7177 PetscValidPointer(mat,1); 7178 PetscCall(MatDestroy(mat)); 7179 PetscFunctionReturn(0); 7180 } 7181 7182 /*@ 7183 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 7184 replaces the index sets by larger ones that represent submatrices with 7185 additional overlap. 7186 7187 Collective on Mat 7188 7189 Input Parameters: 7190 + mat - the matrix 7191 . n - the number of index sets 7192 . is - the array of index sets (these index sets will changed during the call) 7193 - ov - the additional overlap requested 7194 7195 Options Database: 7196 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7197 7198 Level: developer 7199 7200 Developer Note: 7201 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. 7202 7203 .seealso: `MatCreateSubMatrices()` 7204 @*/ 7205 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 7206 { 7207 PetscInt i,bs,cbs; 7208 7209 PetscFunctionBegin; 7210 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7211 PetscValidType(mat,1); 7212 PetscValidLogicalCollectiveInt(mat,n,2); 7213 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7214 if (n) { 7215 PetscValidPointer(is,3); 7216 for (i = 0; i < n; i++) PetscValidHeaderSpecific(is[i],IS_CLASSID,3); 7217 } 7218 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7219 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7220 MatCheckPreallocated(mat,1); 7221 7222 if (!ov || !n) PetscFunctionReturn(0); 7223 PetscCheck(mat->ops->increaseoverlap,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7224 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7225 PetscCall((*mat->ops->increaseoverlap)(mat,n,is,ov)); 7226 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7227 PetscCall(MatGetBlockSizes(mat,&bs,&cbs)); 7228 if (bs == cbs) { 7229 for (i=0; i<n; i++) { 7230 PetscCall(ISSetBlockSize(is[i],bs)); 7231 } 7232 } 7233 PetscFunctionReturn(0); 7234 } 7235 7236 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7237 7238 /*@ 7239 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7240 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7241 additional overlap. 7242 7243 Collective on Mat 7244 7245 Input Parameters: 7246 + mat - the matrix 7247 . n - the number of index sets 7248 . is - the array of index sets (these index sets will changed during the call) 7249 - ov - the additional overlap requested 7250 7251 Options Database: 7252 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7253 7254 Level: developer 7255 7256 .seealso: `MatCreateSubMatrices()` 7257 @*/ 7258 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7259 { 7260 PetscInt i; 7261 7262 PetscFunctionBegin; 7263 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7264 PetscValidType(mat,1); 7265 PetscCheck(n >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %" PetscInt_FMT,n); 7266 if (n) { 7267 PetscValidPointer(is,3); 7268 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7269 } 7270 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7271 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7272 MatCheckPreallocated(mat,1); 7273 if (!ov) PetscFunctionReturn(0); 7274 PetscCall(PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0)); 7275 for (i=0; i<n; i++) { 7276 PetscCall(MatIncreaseOverlapSplit_Single(mat,&is[i],ov)); 7277 } 7278 PetscCall(PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0)); 7279 PetscFunctionReturn(0); 7280 } 7281 7282 /*@ 7283 MatGetBlockSize - Returns the matrix block size. 7284 7285 Not Collective 7286 7287 Input Parameter: 7288 . mat - the matrix 7289 7290 Output Parameter: 7291 . bs - block size 7292 7293 Notes: 7294 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7295 7296 If the block size has not been set yet this routine returns 1. 7297 7298 Level: intermediate 7299 7300 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSizes()` 7301 @*/ 7302 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7303 { 7304 PetscFunctionBegin; 7305 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7306 PetscValidIntPointer(bs,2); 7307 *bs = PetscAbs(mat->rmap->bs); 7308 PetscFunctionReturn(0); 7309 } 7310 7311 /*@ 7312 MatGetBlockSizes - Returns the matrix block row and column sizes. 7313 7314 Not Collective 7315 7316 Input Parameter: 7317 . mat - the matrix 7318 7319 Output Parameters: 7320 + rbs - row block size 7321 - cbs - column block size 7322 7323 Notes: 7324 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7325 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7326 7327 If a block size has not been set yet this routine returns 1. 7328 7329 Level: intermediate 7330 7331 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatSetBlockSizes()` 7332 @*/ 7333 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7334 { 7335 PetscFunctionBegin; 7336 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7337 if (rbs) PetscValidIntPointer(rbs,2); 7338 if (cbs) PetscValidIntPointer(cbs,3); 7339 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7340 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7341 PetscFunctionReturn(0); 7342 } 7343 7344 /*@ 7345 MatSetBlockSize - Sets the matrix block size. 7346 7347 Logically Collective on Mat 7348 7349 Input Parameters: 7350 + mat - the matrix 7351 - bs - block size 7352 7353 Notes: 7354 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7355 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7356 7357 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7358 is compatible with the matrix local sizes. 7359 7360 Level: intermediate 7361 7362 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()` 7363 @*/ 7364 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7365 { 7366 PetscFunctionBegin; 7367 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7368 PetscValidLogicalCollectiveInt(mat,bs,2); 7369 PetscCall(MatSetBlockSizes(mat,bs,bs)); 7370 PetscFunctionReturn(0); 7371 } 7372 7373 typedef struct { 7374 PetscInt n; 7375 IS *is; 7376 Mat *mat; 7377 PetscObjectState nonzerostate; 7378 Mat C; 7379 } EnvelopeData; 7380 7381 static PetscErrorCode EnvelopeDataDestroy(EnvelopeData *edata) 7382 { 7383 for (PetscInt i=0; i<edata->n; i++) { 7384 PetscCall(ISDestroy(&edata->is[i])); 7385 } 7386 PetscCall(PetscFree(edata->is)); 7387 PetscCall(PetscFree(edata)); 7388 return 0; 7389 } 7390 7391 /* 7392 MatComputeVariableBlockEnvelope - Given a matrix whose nonzeros are in blocks along the diagonal this computes and stores 7393 the sizes of these blocks in the matrix. An individual block may lie over several processes. 7394 7395 Collective on mat 7396 7397 Input Parameter: 7398 . mat - the matrix 7399 7400 Notes: 7401 There can be zeros within the blocks 7402 7403 The blocks can overlap between processes, including laying on more than two processes 7404 7405 */ 7406 static PetscErrorCode MatComputeVariableBlockEnvelope(Mat mat) 7407 { 7408 PetscInt n,*sizes,*starts,i = 0,env = 0, tbs = 0, lblocks = 0,rstart,II,ln = 0,cnt = 0,cstart,cend; 7409 PetscInt *diag,*odiag,sc; 7410 VecScatter scatter; 7411 PetscScalar *seqv; 7412 const PetscScalar *parv; 7413 const PetscInt *ia,*ja; 7414 PetscBool set,flag,done; 7415 Mat AA = mat,A; 7416 MPI_Comm comm; 7417 PetscMPIInt rank,size,tag; 7418 MPI_Status status; 7419 PetscContainer container; 7420 EnvelopeData *edata; 7421 Vec seq,par; 7422 IS isglobal; 7423 7424 PetscFunctionBegin; 7425 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7426 PetscCall(MatIsSymmetricKnown(mat,&set,&flag)); 7427 if (!set || !flag) { 7428 /* TOO: only needs nonzero structure of transpose */ 7429 PetscCall(MatTranspose(mat,MAT_INITIAL_MATRIX,&AA)); 7430 PetscCall(MatAXPY(AA,1.0,mat,DIFFERENT_NONZERO_PATTERN)); 7431 } 7432 PetscCall(MatAIJGetLocalMat(AA,&A)); 7433 PetscCall(MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7434 PetscCheck(done,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Unable to get IJ structure from matrix"); 7435 7436 PetscCall(MatGetLocalSize(mat,&n,NULL)); 7437 PetscCall(PetscObjectGetNewTag((PetscObject)mat,&tag)); 7438 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 7439 PetscCallMPI(MPI_Comm_size(comm,&size)); 7440 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 7441 7442 PetscCall(PetscMalloc2(n,&sizes,n,&starts)); 7443 7444 if (rank > 0) { 7445 PetscCallMPI(MPI_Recv(&env,1,MPIU_INT,rank-1,tag,comm,&status)); 7446 PetscCallMPI(MPI_Recv(&tbs,1,MPIU_INT,rank-1,tag,comm,&status)); 7447 } 7448 PetscCall(MatGetOwnershipRange(mat,&rstart,NULL)); 7449 for (i=0; i<n; i++) { 7450 env = PetscMax(env,ja[ia[i+1]-1]); 7451 II = rstart + i; 7452 if (env == II) { 7453 starts[lblocks] = tbs; 7454 sizes[lblocks++] = 1 + II - tbs; 7455 tbs = 1 + II; 7456 } 7457 } 7458 if (rank < size-1) { 7459 PetscCallMPI(MPI_Send(&env,1,MPIU_INT,rank+1,tag,comm)); 7460 PetscCallMPI(MPI_Send(&tbs,1,MPIU_INT,rank+1,tag,comm)); 7461 } 7462 7463 PetscCall(MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ia,&ja,&done)); 7464 if (!set || !flag) { 7465 PetscCall(MatDestroy(&AA)); 7466 } 7467 PetscCall(MatDestroy(&A)); 7468 7469 PetscCall(PetscNew(&edata)); 7470 PetscCall(MatGetNonzeroState(mat,&edata->nonzerostate)); 7471 edata->n = lblocks; 7472 /* create IS needed for extracting blocks from the original matrix */ 7473 PetscCall(PetscMalloc1(lblocks,&edata->is)); 7474 for (PetscInt i=0; i<lblocks; i++) { 7475 PetscCall(ISCreateStride(PETSC_COMM_SELF,sizes[i],starts[i],1,&edata->is[i])); 7476 } 7477 7478 /* Create the resulting inverse matrix structure with preallocation information */ 7479 PetscCall(MatCreate(PetscObjectComm((PetscObject)mat),&edata->C)); 7480 PetscCall(MatSetSizes(edata->C,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N)); 7481 PetscCall(MatSetBlockSizesFromMats(edata->C,mat,mat)); 7482 PetscCall(MatSetType(edata->C,MATAIJ)); 7483 7484 /* Communicate the start and end of each row, from each block to the correct rank */ 7485 /* TODO: Use PetscSF instead of VecScatter */ 7486 for (PetscInt i=0; i<lblocks; i++) ln += sizes[i]; 7487 PetscCall(VecCreateSeq(PETSC_COMM_SELF,2*ln,&seq)); 7488 PetscCall(VecGetArrayWrite(seq,&seqv)); 7489 for (PetscInt i=0; i<lblocks; i++) { 7490 for (PetscInt j=0; j<sizes[i]; j++) { 7491 seqv[cnt] = starts[i]; 7492 seqv[cnt+1] = starts[i] + sizes[i]; 7493 cnt += 2; 7494 } 7495 } 7496 PetscCall(VecRestoreArrayWrite(seq,&seqv)); 7497 PetscCallMPI(MPI_Scan(&cnt,&sc,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat))); 7498 sc -= cnt; 7499 PetscCall(VecCreateMPI(PetscObjectComm((PetscObject)mat),2*mat->rmap->n,2*mat->rmap->N,&par)); 7500 PetscCall(ISCreateStride(PETSC_COMM_SELF,cnt,sc,1,&isglobal)); 7501 PetscCall(VecScatterCreate(seq, NULL ,par, isglobal,&scatter)); 7502 PetscCall(ISDestroy(&isglobal)); 7503 PetscCall(VecScatterBegin(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7504 PetscCall(VecScatterEnd(scatter,seq,par,INSERT_VALUES,SCATTER_FORWARD)); 7505 PetscCall(VecScatterDestroy(&scatter)); 7506 PetscCall(VecDestroy(&seq)); 7507 PetscCall(MatGetOwnershipRangeColumn(mat,&cstart,&cend)); 7508 PetscCall(PetscMalloc2(mat->rmap->n,&diag,mat->rmap->n,&odiag)); 7509 PetscCall(VecGetArrayRead(par,&parv)); 7510 cnt = 0; 7511 PetscCall(MatGetSize(mat,NULL,&n)); 7512 for (PetscInt i=0; i<mat->rmap->n; i++) { 7513 PetscInt start,end,d = 0,od = 0; 7514 7515 start = (PetscInt)PetscRealPart(parv[cnt]); 7516 end = (PetscInt)PetscRealPart(parv[cnt+1]); 7517 cnt += 2; 7518 7519 if (start < cstart) {od += cstart - start + n - cend; d += cend - cstart;} 7520 else if (start < cend) {od += n - cend; d += cend - start;} 7521 else od += n - start; 7522 if (end <= cstart) {od -= cstart - end + n - cend; d -= cend - cstart;} 7523 else if (end < cend) {od -= n - cend; d -= cend - end;} 7524 else od -= n - end; 7525 7526 odiag[i] = od; 7527 diag[i] = d; 7528 } 7529 PetscCall(VecRestoreArrayRead(par,&parv)); 7530 PetscCall(VecDestroy(&par)); 7531 PetscCall(MatXAIJSetPreallocation(edata->C,mat->rmap->bs,diag,odiag,NULL,NULL)); 7532 PetscCall(PetscFree2(diag,odiag)); 7533 PetscCall(PetscFree2(sizes,starts)); 7534 7535 PetscCall(PetscContainerCreate(PETSC_COMM_SELF,&container)); 7536 PetscCall(PetscContainerSetPointer(container,edata)); 7537 PetscCall(PetscContainerSetUserDestroy(container,(PetscErrorCode (*)(void*))EnvelopeDataDestroy)); 7538 PetscCall(PetscObjectCompose((PetscObject)mat,"EnvelopeData",(PetscObject)container)); 7539 PetscCall(PetscObjectDereference((PetscObject)container)); 7540 PetscFunctionReturn(0); 7541 } 7542 7543 /*@ 7544 MatInvertVariableBlockEnvelope - set matrix C to be the inverted block diagonal of matrix A 7545 7546 Collective on Mat 7547 7548 Input Parameters: 7549 . A - the matrix 7550 7551 Output Parameters: 7552 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 7553 7554 Notes: 7555 For efficiency the matrix A should have all the nonzero entries clustered in smallish blocks along the diagonal. 7556 7557 Level: advanced 7558 7559 .seealso: MatInvertBlockDiagonal(), MatComputeBlockDiagonal() 7560 @*/ 7561 PetscErrorCode MatInvertVariableBlockEnvelope(Mat A,MatReuse reuse, Mat *C) 7562 { 7563 PetscContainer container; 7564 EnvelopeData *edata; 7565 PetscObjectState nonzerostate; 7566 7567 PetscFunctionBegin; 7568 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7569 if (!container) { 7570 PetscCall(MatComputeVariableBlockEnvelope(A)); 7571 PetscCall(PetscObjectQuery((PetscObject)A,"EnvelopeData",(PetscObject*)&container)); 7572 } 7573 PetscCall(PetscContainerGetPointer(container,(void**)&edata)); 7574 PetscCall(MatGetNonzeroState(A,&nonzerostate)); 7575 PetscCheck(nonzerostate <= edata->nonzerostate,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot handle changes to matrix nonzero structure"); 7576 PetscCheck(reuse != MAT_REUSE_MATRIX || *C == edata->C,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C matrix must be the same as previously output"); 7577 7578 PetscCall(MatCreateSubMatrices(A,edata->n,edata->is,edata->is,MAT_INITIAL_MATRIX,&edata->mat)); 7579 *C = edata->C; 7580 7581 for (PetscInt i=0; i<edata->n; i++) { 7582 Mat D; 7583 PetscScalar *dvalues; 7584 7585 PetscCall(MatConvert(edata->mat[i], MATSEQDENSE,MAT_INITIAL_MATRIX,&D)); 7586 PetscCall(MatSetOption(*C,MAT_ROW_ORIENTED,PETSC_FALSE)); 7587 PetscCall(MatSeqDenseInvert(D)); 7588 PetscCall(MatDenseGetArray(D,&dvalues)); 7589 PetscCall(MatSetValuesIS(*C,edata->is[i],edata->is[i],dvalues,INSERT_VALUES)); 7590 PetscCall(MatDestroy(&D)); 7591 } 7592 PetscCall(MatDestroySubMatrices(edata->n,&edata->mat)); 7593 PetscCall(MatAssemblyBegin(*C,MAT_FINAL_ASSEMBLY)); 7594 PetscCall(MatAssemblyEnd(*C,MAT_FINAL_ASSEMBLY)); 7595 PetscFunctionReturn(0); 7596 } 7597 7598 /*@ 7599 MatSetVariableBlockSizes - Sets diagonal point-blocks of the matrix that need not be of the same size 7600 7601 Logically Collective on Mat 7602 7603 Input Parameters: 7604 + mat - the matrix 7605 . nblocks - the number of blocks on this process, each block can only exist on a single process 7606 - bsizes - the block sizes 7607 7608 Notes: 7609 Currently used by PCVPBJACOBI for AIJ matrices 7610 7611 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. 7612 7613 Level: intermediate 7614 7615 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatGetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()`, `PCVPBJACOBI` 7616 @*/ 7617 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7618 { 7619 PetscInt i,ncnt = 0, nlocal; 7620 7621 PetscFunctionBegin; 7622 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7623 PetscCheck(nblocks >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7624 PetscCall(MatGetLocalSize(mat,&nlocal,NULL)); 7625 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7626 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); 7627 PetscCall(PetscFree(mat->bsizes)); 7628 mat->nblocks = nblocks; 7629 PetscCall(PetscMalloc1(nblocks,&mat->bsizes)); 7630 PetscCall(PetscArraycpy(mat->bsizes,bsizes,nblocks)); 7631 PetscFunctionReturn(0); 7632 } 7633 7634 /*@C 7635 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7636 7637 Logically Collective on Mat 7638 7639 Input Parameter: 7640 . mat - the matrix 7641 7642 Output Parameters: 7643 + nblocks - the number of blocks on this process 7644 - bsizes - the block sizes 7645 7646 Notes: Currently not supported from Fortran 7647 7648 Level: intermediate 7649 7650 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()`, `MatGetBlockSizes()`, `MatSetVariableBlockSizes()`, `MatComputeVariableBlockEnvelope()` 7651 @*/ 7652 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7653 { 7654 PetscFunctionBegin; 7655 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7656 *nblocks = mat->nblocks; 7657 *bsizes = mat->bsizes; 7658 PetscFunctionReturn(0); 7659 } 7660 7661 /*@ 7662 MatSetBlockSizes - Sets the matrix block row and column sizes. 7663 7664 Logically Collective on Mat 7665 7666 Input Parameters: 7667 + mat - the matrix 7668 . rbs - row block size 7669 - cbs - column block size 7670 7671 Notes: 7672 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7673 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7674 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7675 7676 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7677 are compatible with the matrix local sizes. 7678 7679 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7680 7681 Level: intermediate 7682 7683 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSize()`, `MatGetBlockSizes()` 7684 @*/ 7685 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7686 { 7687 PetscFunctionBegin; 7688 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7689 PetscValidLogicalCollectiveInt(mat,rbs,2); 7690 PetscValidLogicalCollectiveInt(mat,cbs,3); 7691 if (mat->ops->setblocksizes) PetscCall((*mat->ops->setblocksizes)(mat,rbs,cbs)); 7692 if (mat->rmap->refcnt) { 7693 ISLocalToGlobalMapping l2g = NULL; 7694 PetscLayout nmap = NULL; 7695 7696 PetscCall(PetscLayoutDuplicate(mat->rmap,&nmap)); 7697 if (mat->rmap->mapping) { 7698 PetscCall(ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g)); 7699 } 7700 PetscCall(PetscLayoutDestroy(&mat->rmap)); 7701 mat->rmap = nmap; 7702 mat->rmap->mapping = l2g; 7703 } 7704 if (mat->cmap->refcnt) { 7705 ISLocalToGlobalMapping l2g = NULL; 7706 PetscLayout nmap = NULL; 7707 7708 PetscCall(PetscLayoutDuplicate(mat->cmap,&nmap)); 7709 if (mat->cmap->mapping) { 7710 PetscCall(ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g)); 7711 } 7712 PetscCall(PetscLayoutDestroy(&mat->cmap)); 7713 mat->cmap = nmap; 7714 mat->cmap->mapping = l2g; 7715 } 7716 PetscCall(PetscLayoutSetBlockSize(mat->rmap,rbs)); 7717 PetscCall(PetscLayoutSetBlockSize(mat->cmap,cbs)); 7718 PetscFunctionReturn(0); 7719 } 7720 7721 /*@ 7722 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7723 7724 Logically Collective on Mat 7725 7726 Input Parameters: 7727 + mat - the matrix 7728 . fromRow - matrix from which to copy row block size 7729 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7730 7731 Level: developer 7732 7733 .seealso: `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, `MatGetBlockSize()`, `MatSetBlockSizes()` 7734 @*/ 7735 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7736 { 7737 PetscFunctionBegin; 7738 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7739 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7740 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7741 if (fromRow->rmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs)); 7742 if (fromCol->cmap->bs > 0) PetscCall(PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs)); 7743 PetscFunctionReturn(0); 7744 } 7745 7746 /*@ 7747 MatResidual - Default routine to calculate the residual. 7748 7749 Collective on Mat 7750 7751 Input Parameters: 7752 + mat - the matrix 7753 . b - the right-hand-side 7754 - x - the approximate solution 7755 7756 Output Parameter: 7757 . r - location to store the residual 7758 7759 Level: developer 7760 7761 .seealso: `PCMGSetResidual()` 7762 @*/ 7763 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7764 { 7765 PetscFunctionBegin; 7766 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7767 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7768 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7769 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7770 PetscValidType(mat,1); 7771 MatCheckPreallocated(mat,1); 7772 PetscCall(PetscLogEventBegin(MAT_Residual,mat,0,0,0)); 7773 if (!mat->ops->residual) { 7774 PetscCall(MatMult(mat,x,r)); 7775 PetscCall(VecAYPX(r,-1.0,b)); 7776 } else { 7777 PetscCall((*mat->ops->residual)(mat,b,x,r)); 7778 } 7779 PetscCall(PetscLogEventEnd(MAT_Residual,mat,0,0,0)); 7780 PetscFunctionReturn(0); 7781 } 7782 7783 /*@C 7784 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7785 7786 Collective on Mat 7787 7788 Input Parameters: 7789 + mat - the matrix 7790 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7791 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7792 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7793 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7794 always used. 7795 7796 Output Parameters: 7797 + n - number of rows in the (possibly compressed) matrix 7798 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7799 . ja - the column indices 7800 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7801 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7802 7803 Level: developer 7804 7805 Notes: 7806 You CANNOT change any of the ia[] or ja[] values. 7807 7808 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7809 7810 Fortran Notes: 7811 In Fortran use 7812 $ 7813 $ PetscInt ia(1), ja(1) 7814 $ PetscOffset iia, jja 7815 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7816 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7817 7818 or 7819 $ 7820 $ PetscInt, pointer :: ia(:),ja(:) 7821 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7822 $ ! Access the ith and jth entries via ia(i) and ja(j) 7823 7824 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()`, `MatSeqAIJGetArray()` 7825 @*/ 7826 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7827 { 7828 PetscFunctionBegin; 7829 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7830 PetscValidType(mat,1); 7831 PetscValidIntPointer(n,5); 7832 if (ia) PetscValidPointer(ia,6); 7833 if (ja) PetscValidPointer(ja,7); 7834 PetscValidBoolPointer(done,8); 7835 MatCheckPreallocated(mat,1); 7836 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7837 else { 7838 *done = PETSC_TRUE; 7839 PetscCall(PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0)); 7840 PetscCall((*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7841 PetscCall(PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0)); 7842 } 7843 PetscFunctionReturn(0); 7844 } 7845 7846 /*@C 7847 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7848 7849 Collective on Mat 7850 7851 Input Parameters: 7852 + mat - the matrix 7853 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7854 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7855 symmetrized 7856 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7857 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7858 always used. 7859 . n - number of columns in the (possibly compressed) matrix 7860 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7861 - ja - the row indices 7862 7863 Output Parameters: 7864 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7865 7866 Level: developer 7867 7868 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7869 @*/ 7870 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7871 { 7872 PetscFunctionBegin; 7873 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7874 PetscValidType(mat,1); 7875 PetscValidIntPointer(n,5); 7876 if (ia) PetscValidPointer(ia,6); 7877 if (ja) PetscValidPointer(ja,7); 7878 PetscValidBoolPointer(done,8); 7879 MatCheckPreallocated(mat,1); 7880 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7881 else { 7882 *done = PETSC_TRUE; 7883 PetscCall((*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7884 } 7885 PetscFunctionReturn(0); 7886 } 7887 7888 /*@C 7889 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7890 MatGetRowIJ(). 7891 7892 Collective on Mat 7893 7894 Input Parameters: 7895 + mat - the matrix 7896 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7897 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7898 symmetrized 7899 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7900 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7901 always used. 7902 . n - size of (possibly compressed) matrix 7903 . ia - the row pointers 7904 - ja - the column indices 7905 7906 Output Parameters: 7907 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7908 7909 Note: 7910 This routine zeros out n, ia, and ja. This is to prevent accidental 7911 us of the array after it has been restored. If you pass NULL, it will 7912 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7913 7914 Level: developer 7915 7916 .seealso: `MatGetRowIJ()`, `MatRestoreColumnIJ()` 7917 @*/ 7918 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7919 { 7920 PetscFunctionBegin; 7921 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7922 PetscValidType(mat,1); 7923 if (ia) PetscValidPointer(ia,6); 7924 if (ja) PetscValidPointer(ja,7); 7925 PetscValidBoolPointer(done,8); 7926 MatCheckPreallocated(mat,1); 7927 7928 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7929 else { 7930 *done = PETSC_TRUE; 7931 PetscCall((*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7932 if (n) *n = 0; 7933 if (ia) *ia = NULL; 7934 if (ja) *ja = NULL; 7935 } 7936 PetscFunctionReturn(0); 7937 } 7938 7939 /*@C 7940 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7941 MatGetColumnIJ(). 7942 7943 Collective on Mat 7944 7945 Input Parameters: 7946 + mat - the matrix 7947 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7948 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7949 symmetrized 7950 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7951 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7952 always used. 7953 7954 Output Parameters: 7955 + n - size of (possibly compressed) matrix 7956 . ia - the column pointers 7957 . ja - the row indices 7958 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7959 7960 Level: developer 7961 7962 .seealso: `MatGetColumnIJ()`, `MatRestoreRowIJ()` 7963 @*/ 7964 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7965 { 7966 PetscFunctionBegin; 7967 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7968 PetscValidType(mat,1); 7969 if (ia) PetscValidPointer(ia,6); 7970 if (ja) PetscValidPointer(ja,7); 7971 PetscValidBoolPointer(done,8); 7972 MatCheckPreallocated(mat,1); 7973 7974 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7975 else { 7976 *done = PETSC_TRUE; 7977 PetscCall((*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done)); 7978 if (n) *n = 0; 7979 if (ia) *ia = NULL; 7980 if (ja) *ja = NULL; 7981 } 7982 PetscFunctionReturn(0); 7983 } 7984 7985 /*@C 7986 MatColoringPatch -Used inside matrix coloring routines that 7987 use MatGetRowIJ() and/or MatGetColumnIJ(). 7988 7989 Collective on Mat 7990 7991 Input Parameters: 7992 + mat - the matrix 7993 . ncolors - max color value 7994 . n - number of entries in colorarray 7995 - colorarray - array indicating color for each column 7996 7997 Output Parameters: 7998 . iscoloring - coloring generated using colorarray information 7999 8000 Level: developer 8001 8002 .seealso: `MatGetRowIJ()`, `MatGetColumnIJ()` 8003 8004 @*/ 8005 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 8006 { 8007 PetscFunctionBegin; 8008 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8009 PetscValidType(mat,1); 8010 PetscValidIntPointer(colorarray,4); 8011 PetscValidPointer(iscoloring,5); 8012 MatCheckPreallocated(mat,1); 8013 8014 if (!mat->ops->coloringpatch) { 8015 PetscCall(ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring)); 8016 } else { 8017 PetscCall((*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring)); 8018 } 8019 PetscFunctionReturn(0); 8020 } 8021 8022 /*@ 8023 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 8024 8025 Logically Collective on Mat 8026 8027 Input Parameter: 8028 . mat - the factored matrix to be reset 8029 8030 Notes: 8031 This routine should be used only with factored matrices formed by in-place 8032 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 8033 format). This option can save memory, for example, when solving nonlinear 8034 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 8035 ILU(0) preconditioner. 8036 8037 Note that one can specify in-place ILU(0) factorization by calling 8038 .vb 8039 PCType(pc,PCILU); 8040 PCFactorSeUseInPlace(pc); 8041 .ve 8042 or by using the options -pc_type ilu -pc_factor_in_place 8043 8044 In-place factorization ILU(0) can also be used as a local 8045 solver for the blocks within the block Jacobi or additive Schwarz 8046 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 8047 for details on setting local solver options. 8048 8049 Most users should employ the simplified KSP interface for linear solvers 8050 instead of working directly with matrix algebra routines such as this. 8051 See, e.g., KSPCreate(). 8052 8053 Level: developer 8054 8055 .seealso: `PCFactorSetUseInPlace()`, `PCFactorGetUseInPlace()` 8056 8057 @*/ 8058 PetscErrorCode MatSetUnfactored(Mat mat) 8059 { 8060 PetscFunctionBegin; 8061 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8062 PetscValidType(mat,1); 8063 MatCheckPreallocated(mat,1); 8064 mat->factortype = MAT_FACTOR_NONE; 8065 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 8066 PetscCall((*mat->ops->setunfactored)(mat)); 8067 PetscFunctionReturn(0); 8068 } 8069 8070 /*MC 8071 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 8072 8073 Synopsis: 8074 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8075 8076 Not collective 8077 8078 Input Parameter: 8079 . x - matrix 8080 8081 Output Parameters: 8082 + xx_v - the Fortran90 pointer to the array 8083 - ierr - error code 8084 8085 Example of Usage: 8086 .vb 8087 PetscScalar, pointer xx_v(:,:) 8088 .... 8089 call MatDenseGetArrayF90(x,xx_v,ierr) 8090 a = xx_v(3) 8091 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8092 .ve 8093 8094 Level: advanced 8095 8096 .seealso: `MatDenseRestoreArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJGetArrayF90()` 8097 8098 M*/ 8099 8100 /*MC 8101 MatDenseRestoreArrayF90 - Restores a matrix array that has been 8102 accessed with MatDenseGetArrayF90(). 8103 8104 Synopsis: 8105 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 8106 8107 Not collective 8108 8109 Input Parameters: 8110 + x - matrix 8111 - xx_v - the Fortran90 pointer to the array 8112 8113 Output Parameter: 8114 . ierr - error code 8115 8116 Example of Usage: 8117 .vb 8118 PetscScalar, pointer xx_v(:,:) 8119 .... 8120 call MatDenseGetArrayF90(x,xx_v,ierr) 8121 a = xx_v(3) 8122 call MatDenseRestoreArrayF90(x,xx_v,ierr) 8123 .ve 8124 8125 Level: advanced 8126 8127 .seealso: `MatDenseGetArrayF90()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatSeqAIJRestoreArrayF90()` 8128 8129 M*/ 8130 8131 /*MC 8132 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 8133 8134 Synopsis: 8135 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8136 8137 Not collective 8138 8139 Input Parameter: 8140 . x - matrix 8141 8142 Output Parameters: 8143 + xx_v - the Fortran90 pointer to the array 8144 - ierr - error code 8145 8146 Example of Usage: 8147 .vb 8148 PetscScalar, pointer xx_v(:) 8149 .... 8150 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8151 a = xx_v(3) 8152 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8153 .ve 8154 8155 Level: advanced 8156 8157 .seealso: `MatSeqAIJRestoreArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseGetArrayF90()` 8158 8159 M*/ 8160 8161 /*MC 8162 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 8163 accessed with MatSeqAIJGetArrayF90(). 8164 8165 Synopsis: 8166 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 8167 8168 Not collective 8169 8170 Input Parameters: 8171 + x - matrix 8172 - xx_v - the Fortran90 pointer to the array 8173 8174 Output Parameter: 8175 . ierr - error code 8176 8177 Example of Usage: 8178 .vb 8179 PetscScalar, pointer xx_v(:) 8180 .... 8181 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 8182 a = xx_v(3) 8183 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 8184 .ve 8185 8186 Level: advanced 8187 8188 .seealso: `MatSeqAIJGetArrayF90()`, `MatSeqAIJGetArray()`, `MatSeqAIJRestoreArray()`, `MatDenseRestoreArrayF90()` 8189 8190 M*/ 8191 8192 /*@ 8193 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 8194 as the original matrix. 8195 8196 Collective on Mat 8197 8198 Input Parameters: 8199 + mat - the original matrix 8200 . isrow - parallel IS containing the rows this processor should obtain 8201 . 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. 8202 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 8203 8204 Output Parameter: 8205 . newmat - the new submatrix, of the same type as the old 8206 8207 Level: advanced 8208 8209 Notes: 8210 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 8211 8212 Some matrix types place restrictions on the row and column indices, such 8213 as that they be sorted or that they be equal to each other. 8214 8215 The index sets may not have duplicate entries. 8216 8217 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 8218 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 8219 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 8220 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 8221 you are finished using it. 8222 8223 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 8224 the input matrix. 8225 8226 If iscol is NULL then all columns are obtained (not supported in Fortran). 8227 8228 Example usage: 8229 Consider the following 8x8 matrix with 34 non-zero values, that is 8230 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 8231 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 8232 as follows: 8233 8234 .vb 8235 1 2 0 | 0 3 0 | 0 4 8236 Proc0 0 5 6 | 7 0 0 | 8 0 8237 9 0 10 | 11 0 0 | 12 0 8238 ------------------------------------- 8239 13 0 14 | 15 16 17 | 0 0 8240 Proc1 0 18 0 | 19 20 21 | 0 0 8241 0 0 0 | 22 23 0 | 24 0 8242 ------------------------------------- 8243 Proc2 25 26 27 | 0 0 28 | 29 0 8244 30 0 0 | 31 32 33 | 0 34 8245 .ve 8246 8247 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 8248 8249 .vb 8250 2 0 | 0 3 0 | 0 8251 Proc0 5 6 | 7 0 0 | 8 8252 ------------------------------- 8253 Proc1 18 0 | 19 20 21 | 0 8254 ------------------------------- 8255 Proc2 26 27 | 0 0 28 | 29 8256 0 0 | 31 32 33 | 0 8257 .ve 8258 8259 .seealso: `MatCreateSubMatrices()`, `MatCreateSubMatricesMPI()`, `MatCreateSubMatrixVirtual()`, `MatSubMatrixVirtualUpdate()` 8260 @*/ 8261 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 8262 { 8263 PetscMPIInt size; 8264 Mat *local; 8265 IS iscoltmp; 8266 PetscBool flg; 8267 8268 PetscFunctionBegin; 8269 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8270 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 8271 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 8272 PetscValidPointer(newmat,5); 8273 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 8274 PetscValidType(mat,1); 8275 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8276 PetscCheck(cll != MAT_IGNORE_MATRIX,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 8277 8278 MatCheckPreallocated(mat,1); 8279 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8280 8281 if (!iscol || isrow == iscol) { 8282 PetscBool stride; 8283 PetscMPIInt grabentirematrix = 0,grab; 8284 PetscCall(PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride)); 8285 if (stride) { 8286 PetscInt first,step,n,rstart,rend; 8287 PetscCall(ISStrideGetInfo(isrow,&first,&step)); 8288 if (step == 1) { 8289 PetscCall(MatGetOwnershipRange(mat,&rstart,&rend)); 8290 if (rstart == first) { 8291 PetscCall(ISGetLocalSize(isrow,&n)); 8292 if (n == rend-rstart) { 8293 grabentirematrix = 1; 8294 } 8295 } 8296 } 8297 } 8298 PetscCall(MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat))); 8299 if (grab) { 8300 PetscCall(PetscInfo(mat,"Getting entire matrix as submatrix\n")); 8301 if (cll == MAT_INITIAL_MATRIX) { 8302 *newmat = mat; 8303 PetscCall(PetscObjectReference((PetscObject)mat)); 8304 } 8305 PetscFunctionReturn(0); 8306 } 8307 } 8308 8309 if (!iscol) { 8310 PetscCall(ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp)); 8311 } else { 8312 iscoltmp = iscol; 8313 } 8314 8315 /* if original matrix is on just one processor then use submatrix generated */ 8316 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 8317 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat)); 8318 goto setproperties; 8319 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 8320 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local)); 8321 *newmat = *local; 8322 PetscCall(PetscFree(local)); 8323 goto setproperties; 8324 } else if (!mat->ops->createsubmatrix) { 8325 /* Create a new matrix type that implements the operation using the full matrix */ 8326 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8327 switch (cll) { 8328 case MAT_INITIAL_MATRIX: 8329 PetscCall(MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat)); 8330 break; 8331 case MAT_REUSE_MATRIX: 8332 PetscCall(MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp)); 8333 break; 8334 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 8335 } 8336 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8337 goto setproperties; 8338 } 8339 8340 PetscCheck(mat->ops->createsubmatrix,PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8341 PetscCall(PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0)); 8342 PetscCall((*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat)); 8343 PetscCall(PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0)); 8344 8345 setproperties: 8346 PetscCall(ISEqualUnsorted(isrow,iscoltmp,&flg)); 8347 if (flg) PetscCall(MatPropagateSymmetryOptions(mat,*newmat)); 8348 if (!iscol) PetscCall(ISDestroy(&iscoltmp)); 8349 if (*newmat && cll == MAT_INITIAL_MATRIX) PetscCall(PetscObjectStateIncrease((PetscObject)*newmat)); 8350 PetscFunctionReturn(0); 8351 } 8352 8353 /*@ 8354 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 8355 8356 Not Collective 8357 8358 Input Parameters: 8359 + A - the matrix we wish to propagate options from 8360 - B - the matrix we wish to propagate options to 8361 8362 Level: beginner 8363 8364 Notes: Propagates the options associated to MAT_SYMMETRY_ETERNAL, MAT_STRUCTURALLY_SYMMETRIC, MAT_HERMITIAN, MAT_SPD and MAT_SYMMETRIC 8365 8366 .seealso: `MatSetOption()` 8367 @*/ 8368 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) 8369 { 8370 PetscFunctionBegin; 8371 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8372 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 8373 if (A->symmetric_eternal) { /* symmetric_eternal does not have a corresponding *set flag */ 8374 PetscCall(MatSetOption(B,MAT_SYMMETRY_ETERNAL,A->symmetric_eternal)); 8375 } 8376 if (A->structurally_symmetric_set) PetscCall(MatSetOption(B,MAT_STRUCTURALLY_SYMMETRIC,A->structurally_symmetric)); 8377 if (A->hermitian_set) PetscCall(MatSetOption(B,MAT_HERMITIAN,A->hermitian)); 8378 if (A->spd_set) PetscCall(MatSetOption(B,MAT_SPD,A->spd)); 8379 if (A->symmetric_set) PetscCall(MatSetOption(B,MAT_SYMMETRIC,A->symmetric)); 8380 PetscFunctionReturn(0); 8381 } 8382 8383 /*@ 8384 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 8385 used during the assembly process to store values that belong to 8386 other processors. 8387 8388 Not Collective 8389 8390 Input Parameters: 8391 + mat - the matrix 8392 . size - the initial size of the stash. 8393 - bsize - the initial size of the block-stash(if used). 8394 8395 Options Database Keys: 8396 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 8397 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 8398 8399 Level: intermediate 8400 8401 Notes: 8402 The block-stash is used for values set with MatSetValuesBlocked() while 8403 the stash is used for values set with MatSetValues() 8404 8405 Run with the option -info and look for output of the form 8406 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 8407 to determine the appropriate value, MM, to use for size and 8408 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 8409 to determine the value, BMM to use for bsize 8410 8411 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashGetInfo()` 8412 8413 @*/ 8414 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 8415 { 8416 PetscFunctionBegin; 8417 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8418 PetscValidType(mat,1); 8419 PetscCall(MatStashSetInitialSize_Private(&mat->stash,size)); 8420 PetscCall(MatStashSetInitialSize_Private(&mat->bstash,bsize)); 8421 PetscFunctionReturn(0); 8422 } 8423 8424 /*@ 8425 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 8426 the matrix 8427 8428 Neighbor-wise Collective on Mat 8429 8430 Input Parameters: 8431 + mat - the matrix 8432 . x,y - the vectors 8433 - w - where the result is stored 8434 8435 Level: intermediate 8436 8437 Notes: 8438 w may be the same vector as y. 8439 8440 This allows one to use either the restriction or interpolation (its transpose) 8441 matrix to do the interpolation 8442 8443 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8444 8445 @*/ 8446 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8447 { 8448 PetscInt M,N,Ny; 8449 8450 PetscFunctionBegin; 8451 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8452 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8453 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8454 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8455 PetscCall(MatGetSize(A,&M,&N)); 8456 PetscCall(VecGetSize(y,&Ny)); 8457 if (M == Ny) { 8458 PetscCall(MatMultAdd(A,x,y,w)); 8459 } else { 8460 PetscCall(MatMultTransposeAdd(A,x,y,w)); 8461 } 8462 PetscFunctionReturn(0); 8463 } 8464 8465 /*@ 8466 MatInterpolate - y = A*x or A'*x depending on the shape of 8467 the matrix 8468 8469 Neighbor-wise Collective on Mat 8470 8471 Input Parameters: 8472 + mat - the matrix 8473 - x,y - the vectors 8474 8475 Level: intermediate 8476 8477 Notes: 8478 This allows one to use either the restriction or interpolation (its transpose) 8479 matrix to do the interpolation 8480 8481 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatRestrict()` 8482 8483 @*/ 8484 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8485 { 8486 PetscInt M,N,Ny; 8487 8488 PetscFunctionBegin; 8489 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8490 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8491 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8492 PetscCall(MatGetSize(A,&M,&N)); 8493 PetscCall(VecGetSize(y,&Ny)); 8494 if (M == Ny) { 8495 PetscCall(MatMult(A,x,y)); 8496 } else { 8497 PetscCall(MatMultTranspose(A,x,y)); 8498 } 8499 PetscFunctionReturn(0); 8500 } 8501 8502 /*@ 8503 MatRestrict - y = A*x or A'*x 8504 8505 Neighbor-wise Collective on Mat 8506 8507 Input Parameters: 8508 + mat - the matrix 8509 - x,y - the vectors 8510 8511 Level: intermediate 8512 8513 Notes: 8514 This allows one to use either the restriction or interpolation (its transpose) 8515 matrix to do the restriction 8516 8517 .seealso: `MatMultAdd()`, `MatMultTransposeAdd()`, `MatInterpolate()` 8518 8519 @*/ 8520 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8521 { 8522 PetscInt M,N,Ny; 8523 8524 PetscFunctionBegin; 8525 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8526 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8527 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8528 PetscCall(MatGetSize(A,&M,&N)); 8529 PetscCall(VecGetSize(y,&Ny)); 8530 if (M == Ny) { 8531 PetscCall(MatMult(A,x,y)); 8532 } else { 8533 PetscCall(MatMultTranspose(A,x,y)); 8534 } 8535 PetscFunctionReturn(0); 8536 } 8537 8538 /*@ 8539 MatMatInterpolateAdd - Y = W + A*X or W + A'*X 8540 8541 Neighbor-wise Collective on Mat 8542 8543 Input Parameters: 8544 + mat - the matrix 8545 - w, x - the input dense matrices 8546 8547 Output Parameters: 8548 . y - the output dense matrix 8549 8550 Level: intermediate 8551 8552 Notes: 8553 This allows one to use either the restriction or interpolation (its transpose) 8554 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8555 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8556 8557 .seealso: `MatInterpolateAdd()`, `MatMatInterpolate()`, `MatMatRestrict()` 8558 8559 @*/ 8560 PetscErrorCode MatMatInterpolateAdd(Mat A,Mat x,Mat w,Mat *y) 8561 { 8562 PetscInt M,N,Mx,Nx,Mo,My = 0,Ny = 0; 8563 PetscBool trans = PETSC_TRUE; 8564 MatReuse reuse = MAT_INITIAL_MATRIX; 8565 8566 PetscFunctionBegin; 8567 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8568 PetscValidHeaderSpecific(x,MAT_CLASSID,2); 8569 PetscValidType(x,2); 8570 if (w) PetscValidHeaderSpecific(w,MAT_CLASSID,3); 8571 if (*y) PetscValidHeaderSpecific(*y,MAT_CLASSID,4); 8572 PetscCall(MatGetSize(A,&M,&N)); 8573 PetscCall(MatGetSize(x,&Mx,&Nx)); 8574 if (N == Mx) trans = PETSC_FALSE; 8575 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); 8576 Mo = trans ? N : M; 8577 if (*y) { 8578 PetscCall(MatGetSize(*y,&My,&Ny)); 8579 if (Mo == My && Nx == Ny) { reuse = MAT_REUSE_MATRIX; } 8580 else { 8581 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); 8582 PetscCall(MatDestroy(y)); 8583 } 8584 } 8585 8586 if (w && *y == w) { /* this is to minimize changes in PCMG */ 8587 PetscBool flg; 8588 8589 PetscCall(PetscObjectQuery((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject*)&w)); 8590 if (w) { 8591 PetscInt My,Ny,Mw,Nw; 8592 8593 PetscCall(PetscObjectTypeCompare((PetscObject)*y,((PetscObject)w)->type_name,&flg)); 8594 PetscCall(MatGetSize(*y,&My,&Ny)); 8595 PetscCall(MatGetSize(w,&Mw,&Nw)); 8596 if (!flg || My != Mw || Ny != Nw) w = NULL; 8597 } 8598 if (!w) { 8599 PetscCall(MatDuplicate(*y,MAT_COPY_VALUES,&w)); 8600 PetscCall(PetscObjectCompose((PetscObject)*y,"__MatMatIntAdd_w",(PetscObject)w)); 8601 PetscCall(PetscLogObjectParent((PetscObject)*y,(PetscObject)w)); 8602 PetscCall(PetscObjectDereference((PetscObject)w)); 8603 } else { 8604 PetscCall(MatCopy(*y,w,UNKNOWN_NONZERO_PATTERN)); 8605 } 8606 } 8607 if (!trans) { 8608 PetscCall(MatMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8609 } else { 8610 PetscCall(MatTransposeMatMult(A,x,reuse,PETSC_DEFAULT,y)); 8611 } 8612 if (w) PetscCall(MatAXPY(*y,1.0,w,UNKNOWN_NONZERO_PATTERN)); 8613 PetscFunctionReturn(0); 8614 } 8615 8616 /*@ 8617 MatMatInterpolate - Y = A*X or A'*X 8618 8619 Neighbor-wise Collective on Mat 8620 8621 Input Parameters: 8622 + mat - the matrix 8623 - x - the input dense matrix 8624 8625 Output Parameters: 8626 . y - the output dense matrix 8627 8628 Level: intermediate 8629 8630 Notes: 8631 This allows one to use either the restriction or interpolation (its transpose) 8632 matrix to do the interpolation. y matrix can be reused if already created with the proper sizes, 8633 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8634 8635 .seealso: `MatInterpolate()`, `MatRestrict()`, `MatMatRestrict()` 8636 8637 @*/ 8638 PetscErrorCode MatMatInterpolate(Mat A,Mat x,Mat *y) 8639 { 8640 PetscFunctionBegin; 8641 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8642 PetscFunctionReturn(0); 8643 } 8644 8645 /*@ 8646 MatMatRestrict - Y = A*X or A'*X 8647 8648 Neighbor-wise Collective on Mat 8649 8650 Input Parameters: 8651 + mat - the matrix 8652 - x - the input dense matrix 8653 8654 Output Parameters: 8655 . y - the output dense matrix 8656 8657 Level: intermediate 8658 8659 Notes: 8660 This allows one to use either the restriction or interpolation (its transpose) 8661 matrix to do the restriction. y matrix can be reused if already created with the proper sizes, 8662 otherwise it will be recreated. y must be initialized to NULL if not supplied. 8663 8664 .seealso: `MatRestrict()`, `MatInterpolate()`, `MatMatInterpolate()` 8665 @*/ 8666 PetscErrorCode MatMatRestrict(Mat A,Mat x,Mat *y) 8667 { 8668 PetscFunctionBegin; 8669 PetscCall(MatMatInterpolateAdd(A,x,NULL,y)); 8670 PetscFunctionReturn(0); 8671 } 8672 8673 /*@ 8674 MatGetNullSpace - retrieves the null space of a matrix. 8675 8676 Logically Collective on Mat 8677 8678 Input Parameters: 8679 + mat - the matrix 8680 - nullsp - the null space object 8681 8682 Level: developer 8683 8684 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetNullSpace()` 8685 @*/ 8686 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8687 { 8688 PetscFunctionBegin; 8689 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8690 PetscValidPointer(nullsp,2); 8691 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8692 PetscFunctionReturn(0); 8693 } 8694 8695 /*@ 8696 MatSetNullSpace - attaches a null space to a matrix. 8697 8698 Logically Collective on Mat 8699 8700 Input Parameters: 8701 + mat - the matrix 8702 - nullsp - the null space object 8703 8704 Level: advanced 8705 8706 Notes: 8707 This null space is used by the KSP linear solvers to solve singular systems. 8708 8709 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 8710 8711 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 8712 to zero but the linear system will still be solved in a least squares sense. 8713 8714 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8715 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). 8716 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 8717 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 8718 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). 8719 This \hat{b} can be obtained by calling MatNullSpaceRemove() with the null space of the transpose of the matrix. 8720 8721 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 8722 routine also automatically calls MatSetTransposeNullSpace(). 8723 8724 The user should call `MatNullSpaceDestroy()`. 8725 8726 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetTransposeNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, 8727 `KSPSetPCSide()` 8728 @*/ 8729 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8730 { 8731 PetscFunctionBegin; 8732 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8733 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8734 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8735 PetscCall(MatNullSpaceDestroy(&mat->nullsp)); 8736 mat->nullsp = nullsp; 8737 if (mat->symmetric_set && mat->symmetric) { 8738 PetscCall(MatSetTransposeNullSpace(mat,nullsp)); 8739 } 8740 PetscFunctionReturn(0); 8741 } 8742 8743 /*@ 8744 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8745 8746 Logically Collective on Mat 8747 8748 Input Parameters: 8749 + mat - the matrix 8750 - nullsp - the null space object 8751 8752 Level: developer 8753 8754 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatSetTransposeNullSpace()`, `MatSetNullSpace()`, `MatGetNullSpace()` 8755 @*/ 8756 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8757 { 8758 PetscFunctionBegin; 8759 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8760 PetscValidType(mat,1); 8761 PetscValidPointer(nullsp,2); 8762 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8763 PetscFunctionReturn(0); 8764 } 8765 8766 /*@ 8767 MatSetTransposeNullSpace - attaches the null space of a transpose of a matrix to the matrix 8768 8769 Logically Collective on Mat 8770 8771 Input Parameters: 8772 + mat - the matrix 8773 - nullsp - the null space object 8774 8775 Level: advanced 8776 8777 Notes: 8778 This allows solving singular linear systems defined by the transpose of the matrix using KSP solvers with left preconditioning. 8779 8780 See MatSetNullSpace() 8781 8782 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatSetNullSpace()`, `MatGetTransposeNullSpace()`, `MatNullSpaceRemove()`, `KSPSetPCSide()` 8783 @*/ 8784 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8785 { 8786 PetscFunctionBegin; 8787 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8788 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8789 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8790 PetscCall(MatNullSpaceDestroy(&mat->transnullsp)); 8791 mat->transnullsp = nullsp; 8792 PetscFunctionReturn(0); 8793 } 8794 8795 /*@ 8796 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8797 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8798 8799 Logically Collective on Mat 8800 8801 Input Parameters: 8802 + mat - the matrix 8803 - nullsp - the null space object 8804 8805 Level: advanced 8806 8807 Notes: 8808 Overwrites any previous near null space that may have been attached 8809 8810 You can remove the null space by calling this routine with an nullsp of NULL 8811 8812 .seealso: `MatCreate()`, `MatNullSpaceCreate()`, `MatSetNullSpace()`, `MatNullSpaceCreateRigidBody()`, `MatGetNearNullSpace()` 8813 @*/ 8814 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8815 { 8816 PetscFunctionBegin; 8817 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8818 PetscValidType(mat,1); 8819 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8820 MatCheckPreallocated(mat,1); 8821 if (nullsp) PetscCall(PetscObjectReference((PetscObject)nullsp)); 8822 PetscCall(MatNullSpaceDestroy(&mat->nearnullsp)); 8823 mat->nearnullsp = nullsp; 8824 PetscFunctionReturn(0); 8825 } 8826 8827 /*@ 8828 MatGetNearNullSpace - Get null space attached with MatSetNearNullSpace() 8829 8830 Not Collective 8831 8832 Input Parameter: 8833 . mat - the matrix 8834 8835 Output Parameter: 8836 . nullsp - the null space object, NULL if not set 8837 8838 Level: developer 8839 8840 .seealso: `MatSetNearNullSpace()`, `MatGetNullSpace()`, `MatNullSpaceCreate()` 8841 @*/ 8842 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8843 { 8844 PetscFunctionBegin; 8845 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8846 PetscValidType(mat,1); 8847 PetscValidPointer(nullsp,2); 8848 MatCheckPreallocated(mat,1); 8849 *nullsp = mat->nearnullsp; 8850 PetscFunctionReturn(0); 8851 } 8852 8853 /*@C 8854 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8855 8856 Collective on Mat 8857 8858 Input Parameters: 8859 + mat - the matrix 8860 . row - row/column permutation 8861 . fill - expected fill factor >= 1.0 8862 - level - level of fill, for ICC(k) 8863 8864 Notes: 8865 Probably really in-place only when level of fill is zero, otherwise allocates 8866 new space to store factored matrix and deletes previous memory. 8867 8868 Most users should employ the simplified KSP interface for linear solvers 8869 instead of working directly with matrix algebra routines such as this. 8870 See, e.g., KSPCreate(). 8871 8872 Level: developer 8873 8874 .seealso: `MatICCFactorSymbolic()`, `MatLUFactorNumeric()`, `MatCholeskyFactor()` 8875 8876 Developer Note: fortran interface is not autogenerated as the f90 8877 interface definition cannot be generated correctly [due to MatFactorInfo] 8878 8879 @*/ 8880 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8881 { 8882 PetscFunctionBegin; 8883 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8884 PetscValidType(mat,1); 8885 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8886 PetscValidPointer(info,3); 8887 PetscCheck(mat->rmap->N == mat->cmap->N,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8888 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8889 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8890 PetscCheck(mat->ops->iccfactor,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8891 MatCheckPreallocated(mat,1); 8892 PetscCall((*mat->ops->iccfactor)(mat,row,info)); 8893 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8894 PetscFunctionReturn(0); 8895 } 8896 8897 /*@ 8898 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8899 ghosted ones. 8900 8901 Not Collective 8902 8903 Input Parameters: 8904 + mat - the matrix 8905 - diag - the diagonal values, including ghost ones 8906 8907 Level: developer 8908 8909 Notes: 8910 Works only for MPIAIJ and MPIBAIJ matrices 8911 8912 .seealso: `MatDiagonalScale()` 8913 @*/ 8914 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8915 { 8916 PetscMPIInt size; 8917 8918 PetscFunctionBegin; 8919 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8920 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8921 PetscValidType(mat,1); 8922 8923 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8924 PetscCall(PetscLogEventBegin(MAT_Scale,mat,0,0,0)); 8925 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 8926 if (size == 1) { 8927 PetscInt n,m; 8928 PetscCall(VecGetSize(diag,&n)); 8929 PetscCall(MatGetSize(mat,NULL,&m)); 8930 if (m == n) { 8931 PetscCall(MatDiagonalScale(mat,NULL,diag)); 8932 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8933 } else { 8934 PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag)); 8935 } 8936 PetscCall(PetscLogEventEnd(MAT_Scale,mat,0,0,0)); 8937 PetscCall(PetscObjectStateIncrease((PetscObject)mat)); 8938 PetscFunctionReturn(0); 8939 } 8940 8941 /*@ 8942 MatGetInertia - Gets the inertia from a factored matrix 8943 8944 Collective on Mat 8945 8946 Input Parameter: 8947 . mat - the matrix 8948 8949 Output Parameters: 8950 + nneg - number of negative eigenvalues 8951 . nzero - number of zero eigenvalues 8952 - npos - number of positive eigenvalues 8953 8954 Level: advanced 8955 8956 Notes: 8957 Matrix must have been factored by MatCholeskyFactor() 8958 8959 @*/ 8960 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8961 { 8962 PetscFunctionBegin; 8963 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8964 PetscValidType(mat,1); 8965 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8966 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8967 PetscCheck(mat->ops->getinertia,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8968 PetscCall((*mat->ops->getinertia)(mat,nneg,nzero,npos)); 8969 PetscFunctionReturn(0); 8970 } 8971 8972 /* ----------------------------------------------------------------*/ 8973 /*@C 8974 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8975 8976 Neighbor-wise Collective on Mats 8977 8978 Input Parameters: 8979 + mat - the factored matrix 8980 - b - the right-hand-side vectors 8981 8982 Output Parameter: 8983 . x - the result vectors 8984 8985 Notes: 8986 The vectors b and x cannot be the same. I.e., one cannot 8987 call MatSolves(A,x,x). 8988 8989 Notes: 8990 Most users should employ the simplified KSP interface for linear solvers 8991 instead of working directly with matrix algebra routines such as this. 8992 See, e.g., KSPCreate(). 8993 8994 Level: developer 8995 8996 .seealso: `MatSolveAdd()`, `MatSolveTranspose()`, `MatSolveTransposeAdd()`, `MatSolve()` 8997 @*/ 8998 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8999 { 9000 PetscFunctionBegin; 9001 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9002 PetscValidType(mat,1); 9003 PetscCheck(x != b,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 9004 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 9005 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 9006 9007 PetscCheck(mat->ops->solves,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 9008 MatCheckPreallocated(mat,1); 9009 PetscCall(PetscLogEventBegin(MAT_Solves,mat,0,0,0)); 9010 PetscCall((*mat->ops->solves)(mat,b,x)); 9011 PetscCall(PetscLogEventEnd(MAT_Solves,mat,0,0,0)); 9012 PetscFunctionReturn(0); 9013 } 9014 9015 /*@ 9016 MatIsSymmetric - Test whether a matrix is symmetric 9017 9018 Collective on Mat 9019 9020 Input Parameters: 9021 + A - the matrix to test 9022 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 9023 9024 Output Parameters: 9025 . flg - the result 9026 9027 Notes: 9028 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 9029 9030 Level: intermediate 9031 9032 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetricKnown()` 9033 @*/ 9034 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 9035 { 9036 PetscFunctionBegin; 9037 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9038 PetscValidBoolPointer(flg,3); 9039 9040 if (!A->symmetric_set) { 9041 if (!A->ops->issymmetric) { 9042 MatType mattype; 9043 PetscCall(MatGetType(A,&mattype)); 9044 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 9045 } 9046 PetscCall((*A->ops->issymmetric)(A,tol,flg)); 9047 if (!tol) { 9048 PetscCall(MatSetOption(A,MAT_SYMMETRIC,*flg)); 9049 } 9050 } else if (A->symmetric) { 9051 *flg = PETSC_TRUE; 9052 } else if (!tol) { 9053 *flg = PETSC_FALSE; 9054 } else { 9055 if (!A->ops->issymmetric) { 9056 MatType mattype; 9057 PetscCall(MatGetType(A,&mattype)); 9058 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 9059 } 9060 PetscCall((*A->ops->issymmetric)(A,tol,flg)); 9061 } 9062 PetscFunctionReturn(0); 9063 } 9064 9065 /*@ 9066 MatIsHermitian - Test whether a matrix is Hermitian 9067 9068 Collective on Mat 9069 9070 Input Parameters: 9071 + A - the matrix to test 9072 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 9073 9074 Output Parameters: 9075 . flg - the result 9076 9077 Level: intermediate 9078 9079 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, 9080 `MatIsSymmetricKnown()`, `MatIsSymmetric()` 9081 @*/ 9082 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 9083 { 9084 PetscFunctionBegin; 9085 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9086 PetscValidBoolPointer(flg,3); 9087 9088 if (!A->hermitian_set) { 9089 if (!A->ops->ishermitian) { 9090 MatType mattype; 9091 PetscCall(MatGetType(A,&mattype)); 9092 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 9093 } 9094 PetscCall((*A->ops->ishermitian)(A,tol,flg)); 9095 if (!tol) { 9096 PetscCall(MatSetOption(A,MAT_HERMITIAN,*flg)); 9097 } 9098 } else if (A->hermitian) { 9099 *flg = PETSC_TRUE; 9100 } else if (!tol) { 9101 *flg = PETSC_FALSE; 9102 } else { 9103 if (!A->ops->ishermitian) { 9104 MatType mattype; 9105 PetscCall(MatGetType(A,&mattype)); 9106 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 9107 } 9108 PetscCall((*A->ops->ishermitian)(A,tol,flg)); 9109 } 9110 PetscFunctionReturn(0); 9111 } 9112 9113 /*@ 9114 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 9115 9116 Not Collective 9117 9118 Input Parameter: 9119 . A - the matrix to check 9120 9121 Output Parameters: 9122 + set - if the symmetric flag is set (this tells you if the next flag is valid) 9123 - flg - the result 9124 9125 Level: advanced 9126 9127 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 9128 if you want it explicitly checked 9129 9130 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()` 9131 @*/ 9132 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 9133 { 9134 PetscFunctionBegin; 9135 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9136 PetscValidBoolPointer(set,2); 9137 PetscValidBoolPointer(flg,3); 9138 if (A->symmetric_set) { 9139 *set = PETSC_TRUE; 9140 *flg = A->symmetric; 9141 } else { 9142 *set = PETSC_FALSE; 9143 } 9144 PetscFunctionReturn(0); 9145 } 9146 9147 /*@ 9148 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 9149 9150 Not Collective 9151 9152 Input Parameter: 9153 . A - the matrix to check 9154 9155 Output Parameters: 9156 + set - if the hermitian flag is set (this tells you if the next flag is valid) 9157 - flg - the result 9158 9159 Level: advanced 9160 9161 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 9162 if you want it explicitly checked 9163 9164 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsStructurallySymmetric()`, `MatSetOption()`, `MatIsSymmetric()` 9165 @*/ 9166 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 9167 { 9168 PetscFunctionBegin; 9169 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9170 PetscValidBoolPointer(set,2); 9171 PetscValidBoolPointer(flg,3); 9172 if (A->hermitian_set) { 9173 *set = PETSC_TRUE; 9174 *flg = A->hermitian; 9175 } else { 9176 *set = PETSC_FALSE; 9177 } 9178 PetscFunctionReturn(0); 9179 } 9180 9181 /*@ 9182 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 9183 9184 Collective on Mat 9185 9186 Input Parameter: 9187 . A - the matrix to test 9188 9189 Output Parameters: 9190 . flg - the result 9191 9192 Level: intermediate 9193 9194 .seealso: `MatTranspose()`, `MatIsTranspose()`, `MatIsHermitian()`, `MatIsSymmetric()`, `MatSetOption()` 9195 @*/ 9196 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 9197 { 9198 PetscFunctionBegin; 9199 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9200 PetscValidBoolPointer(flg,2); 9201 if (!A->structurally_symmetric_set) { 9202 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); 9203 PetscCall((*A->ops->isstructurallysymmetric)(A,flg)); 9204 PetscCall(MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg)); 9205 } else *flg = A->structurally_symmetric; 9206 PetscFunctionReturn(0); 9207 } 9208 9209 /*@ 9210 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 9211 to be communicated to other processors during the MatAssemblyBegin/End() process 9212 9213 Not collective 9214 9215 Input Parameter: 9216 . vec - the vector 9217 9218 Output Parameters: 9219 + nstash - the size of the stash 9220 . reallocs - the number of additional mallocs incurred. 9221 . bnstash - the size of the block stash 9222 - breallocs - the number of additional mallocs incurred.in the block stash 9223 9224 Level: advanced 9225 9226 .seealso: `MatAssemblyBegin()`, `MatAssemblyEnd()`, `Mat`, `MatStashSetInitialSize()` 9227 9228 @*/ 9229 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 9230 { 9231 PetscFunctionBegin; 9232 PetscCall(MatStashGetInfo_Private(&mat->stash,nstash,reallocs)); 9233 PetscCall(MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs)); 9234 PetscFunctionReturn(0); 9235 } 9236 9237 /*@C 9238 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 9239 parallel layout 9240 9241 Collective on Mat 9242 9243 Input Parameter: 9244 . mat - the matrix 9245 9246 Output Parameters: 9247 + right - (optional) vector that the matrix can be multiplied against 9248 - left - (optional) vector that the matrix vector product can be stored in 9249 9250 Notes: 9251 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(). 9252 9253 Notes: 9254 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 9255 9256 Level: advanced 9257 9258 .seealso: `MatCreate()`, `VecDestroy()` 9259 @*/ 9260 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 9261 { 9262 PetscFunctionBegin; 9263 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9264 PetscValidType(mat,1); 9265 if (mat->ops->getvecs) { 9266 PetscCall((*mat->ops->getvecs)(mat,right,left)); 9267 } else { 9268 PetscInt rbs,cbs; 9269 PetscCall(MatGetBlockSizes(mat,&rbs,&cbs)); 9270 if (right) { 9271 PetscCheck(mat->cmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 9272 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),right)); 9273 PetscCall(VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE)); 9274 PetscCall(VecSetBlockSize(*right,cbs)); 9275 PetscCall(VecSetType(*right,mat->defaultvectype)); 9276 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9277 if (mat->boundtocpu && mat->bindingpropagates) { 9278 PetscCall(VecSetBindingPropagates(*right,PETSC_TRUE)); 9279 PetscCall(VecBindToCPU(*right,PETSC_TRUE)); 9280 } 9281 #endif 9282 PetscCall(PetscLayoutReference(mat->cmap,&(*right)->map)); 9283 } 9284 if (left) { 9285 PetscCheck(mat->rmap->n >= 0,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 9286 PetscCall(VecCreate(PetscObjectComm((PetscObject)mat),left)); 9287 PetscCall(VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE)); 9288 PetscCall(VecSetBlockSize(*left,rbs)); 9289 PetscCall(VecSetType(*left,mat->defaultvectype)); 9290 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 9291 if (mat->boundtocpu && mat->bindingpropagates) { 9292 PetscCall(VecSetBindingPropagates(*left,PETSC_TRUE)); 9293 PetscCall(VecBindToCPU(*left,PETSC_TRUE)); 9294 } 9295 #endif 9296 PetscCall(PetscLayoutReference(mat->rmap,&(*left)->map)); 9297 } 9298 } 9299 PetscFunctionReturn(0); 9300 } 9301 9302 /*@C 9303 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 9304 with default values. 9305 9306 Not Collective 9307 9308 Input Parameters: 9309 . info - the MatFactorInfo data structure 9310 9311 Notes: 9312 The solvers are generally used through the KSP and PC objects, for example 9313 PCLU, PCILU, PCCHOLESKY, PCICC 9314 9315 Level: developer 9316 9317 .seealso: `MatFactorInfo` 9318 9319 Developer Note: fortran interface is not autogenerated as the f90 9320 interface definition cannot be generated correctly [due to MatFactorInfo] 9321 9322 @*/ 9323 9324 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 9325 { 9326 PetscFunctionBegin; 9327 PetscCall(PetscMemzero(info,sizeof(MatFactorInfo))); 9328 PetscFunctionReturn(0); 9329 } 9330 9331 /*@ 9332 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 9333 9334 Collective on Mat 9335 9336 Input Parameters: 9337 + mat - the factored matrix 9338 - is - the index set defining the Schur indices (0-based) 9339 9340 Notes: 9341 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 9342 9343 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 9344 9345 Level: developer 9346 9347 .seealso: `MatGetFactor()`, `MatFactorGetSchurComplement()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSolveSchurComplement()`, 9348 `MatFactorSolveSchurComplementTranspose()`, `MatFactorSolveSchurComplement()` 9349 9350 @*/ 9351 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 9352 { 9353 PetscErrorCode (*f)(Mat,IS); 9354 9355 PetscFunctionBegin; 9356 PetscValidType(mat,1); 9357 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9358 PetscValidType(is,2); 9359 PetscValidHeaderSpecific(is,IS_CLASSID,2); 9360 PetscCheckSameComm(mat,1,is,2); 9361 PetscCheck(mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 9362 PetscCall(PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f)); 9363 PetscCheck(f,PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 9364 PetscCall(MatDestroy(&mat->schur)); 9365 PetscCall((*f)(mat,is)); 9366 PetscCheck(mat->schur,PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 9367 PetscFunctionReturn(0); 9368 } 9369 9370 /*@ 9371 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 9372 9373 Logically Collective on Mat 9374 9375 Input Parameters: 9376 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 9377 . S - location where to return the Schur complement, can be NULL 9378 - status - the status of the Schur complement matrix, can be NULL 9379 9380 Notes: 9381 You must call MatFactorSetSchurIS() before calling this routine. 9382 9383 The routine provides a copy of the Schur matrix stored within the solver data structures. 9384 The caller must destroy the object when it is no longer needed. 9385 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 9386 9387 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) 9388 9389 Developer Notes: 9390 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 9391 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 9392 9393 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9394 9395 Level: advanced 9396 9397 References: 9398 9399 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorSchurStatus` 9400 @*/ 9401 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9402 { 9403 PetscFunctionBegin; 9404 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9405 if (S) PetscValidPointer(S,2); 9406 if (status) PetscValidPointer(status,3); 9407 if (S) { 9408 PetscErrorCode (*f)(Mat,Mat*); 9409 9410 PetscCall(PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f)); 9411 if (f) { 9412 PetscCall((*f)(F,S)); 9413 } else { 9414 PetscCall(MatDuplicate(F->schur,MAT_COPY_VALUES,S)); 9415 } 9416 } 9417 if (status) *status = F->schur_status; 9418 PetscFunctionReturn(0); 9419 } 9420 9421 /*@ 9422 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 9423 9424 Logically Collective on Mat 9425 9426 Input Parameters: 9427 + F - the factored matrix obtained by calling MatGetFactor() 9428 . *S - location where to return the Schur complement, can be NULL 9429 - status - the status of the Schur complement matrix, can be NULL 9430 9431 Notes: 9432 You must call MatFactorSetSchurIS() before calling this routine. 9433 9434 Schur complement mode is currently implemented for sequential matrices. 9435 The routine returns a the Schur Complement stored within the data strutures of the solver. 9436 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 9437 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 9438 9439 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 9440 9441 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 9442 9443 Level: advanced 9444 9445 References: 9446 9447 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9448 @*/ 9449 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 9450 { 9451 PetscFunctionBegin; 9452 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9453 if (S) PetscValidPointer(S,2); 9454 if (status) PetscValidPointer(status,3); 9455 if (S) *S = F->schur; 9456 if (status) *status = F->schur_status; 9457 PetscFunctionReturn(0); 9458 } 9459 9460 /*@ 9461 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 9462 9463 Logically Collective on Mat 9464 9465 Input Parameters: 9466 + F - the factored matrix obtained by calling MatGetFactor() 9467 . *S - location where the Schur complement is stored 9468 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 9469 9470 Notes: 9471 9472 Level: advanced 9473 9474 References: 9475 9476 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorRestoreSchurComplement()`, `MatFactorCreateSchurComplement()`, `MatFactorSchurStatus` 9477 @*/ 9478 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 9479 { 9480 PetscFunctionBegin; 9481 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9482 if (S) { 9483 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 9484 *S = NULL; 9485 } 9486 F->schur_status = status; 9487 PetscCall(MatFactorUpdateSchurStatus_Private(F)); 9488 PetscFunctionReturn(0); 9489 } 9490 9491 /*@ 9492 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9493 9494 Logically Collective on Mat 9495 9496 Input Parameters: 9497 + F - the factored matrix obtained by calling MatGetFactor() 9498 . rhs - location where the right hand side of the Schur complement system is stored 9499 - sol - location where the solution of the Schur complement system has to be returned 9500 9501 Notes: 9502 The sizes of the vectors should match the size of the Schur complement 9503 9504 Must be called after MatFactorSetSchurIS() 9505 9506 Level: advanced 9507 9508 References: 9509 9510 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplement()` 9511 @*/ 9512 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9513 { 9514 PetscFunctionBegin; 9515 PetscValidType(F,1); 9516 PetscValidType(rhs,2); 9517 PetscValidType(sol,3); 9518 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9519 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9520 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9521 PetscCheckSameComm(F,1,rhs,2); 9522 PetscCheckSameComm(F,1,sol,3); 9523 PetscCall(MatFactorFactorizeSchurComplement(F)); 9524 switch (F->schur_status) { 9525 case MAT_FACTOR_SCHUR_FACTORED: 9526 PetscCall(MatSolveTranspose(F->schur,rhs,sol)); 9527 break; 9528 case MAT_FACTOR_SCHUR_INVERTED: 9529 PetscCall(MatMultTranspose(F->schur,rhs,sol)); 9530 break; 9531 default: 9532 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9533 } 9534 PetscFunctionReturn(0); 9535 } 9536 9537 /*@ 9538 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9539 9540 Logically Collective on Mat 9541 9542 Input Parameters: 9543 + F - the factored matrix obtained by calling MatGetFactor() 9544 . rhs - location where the right hand side of the Schur complement system is stored 9545 - sol - location where the solution of the Schur complement system has to be returned 9546 9547 Notes: 9548 The sizes of the vectors should match the size of the Schur complement 9549 9550 Must be called after MatFactorSetSchurIS() 9551 9552 Level: advanced 9553 9554 References: 9555 9556 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorSolveSchurComplementTranspose()` 9557 @*/ 9558 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9559 { 9560 PetscFunctionBegin; 9561 PetscValidType(F,1); 9562 PetscValidType(rhs,2); 9563 PetscValidType(sol,3); 9564 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9565 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9566 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9567 PetscCheckSameComm(F,1,rhs,2); 9568 PetscCheckSameComm(F,1,sol,3); 9569 PetscCall(MatFactorFactorizeSchurComplement(F)); 9570 switch (F->schur_status) { 9571 case MAT_FACTOR_SCHUR_FACTORED: 9572 PetscCall(MatSolve(F->schur,rhs,sol)); 9573 break; 9574 case MAT_FACTOR_SCHUR_INVERTED: 9575 PetscCall(MatMult(F->schur,rhs,sol)); 9576 break; 9577 default: 9578 SETERRQ(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %d",F->schur_status); 9579 } 9580 PetscFunctionReturn(0); 9581 } 9582 9583 /*@ 9584 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9585 9586 Logically Collective on Mat 9587 9588 Input Parameters: 9589 . F - the factored matrix obtained by calling MatGetFactor() 9590 9591 Notes: 9592 Must be called after MatFactorSetSchurIS(). 9593 9594 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9595 9596 Level: advanced 9597 9598 References: 9599 9600 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorGetSchurComplement()`, `MatFactorCreateSchurComplement()` 9601 @*/ 9602 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9603 { 9604 PetscFunctionBegin; 9605 PetscValidType(F,1); 9606 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9607 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9608 PetscCall(MatFactorFactorizeSchurComplement(F)); 9609 PetscCall(MatFactorInvertSchurComplement_Private(F)); 9610 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9611 PetscFunctionReturn(0); 9612 } 9613 9614 /*@ 9615 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9616 9617 Logically Collective on Mat 9618 9619 Input Parameters: 9620 . F - the factored matrix obtained by calling MatGetFactor() 9621 9622 Notes: 9623 Must be called after MatFactorSetSchurIS(). 9624 9625 Level: advanced 9626 9627 References: 9628 9629 .seealso: `MatGetFactor()`, `MatFactorSetSchurIS()`, `MatFactorInvertSchurComplement()` 9630 @*/ 9631 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9632 { 9633 PetscFunctionBegin; 9634 PetscValidType(F,1); 9635 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9636 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9637 PetscCall(MatFactorFactorizeSchurComplement_Private(F)); 9638 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9639 PetscFunctionReturn(0); 9640 } 9641 9642 /*@ 9643 MatPtAP - Creates the matrix product C = P^T * A * P 9644 9645 Neighbor-wise Collective on Mat 9646 9647 Input Parameters: 9648 + A - the matrix 9649 . P - the projection matrix 9650 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9651 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9652 if the result is a dense matrix this is irrelevant 9653 9654 Output Parameters: 9655 . C - the product matrix 9656 9657 Notes: 9658 C will be created and must be destroyed by the user with MatDestroy(). 9659 9660 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9661 9662 Level: intermediate 9663 9664 .seealso: `MatMatMult()`, `MatRARt()` 9665 @*/ 9666 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9667 { 9668 PetscFunctionBegin; 9669 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9670 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9671 9672 if (scall == MAT_INITIAL_MATRIX) { 9673 PetscCall(MatProductCreate(A,P,NULL,C)); 9674 PetscCall(MatProductSetType(*C,MATPRODUCT_PtAP)); 9675 PetscCall(MatProductSetAlgorithm(*C,"default")); 9676 PetscCall(MatProductSetFill(*C,fill)); 9677 9678 (*C)->product->api_user = PETSC_TRUE; 9679 PetscCall(MatProductSetFromOptions(*C)); 9680 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); 9681 PetscCall(MatProductSymbolic(*C)); 9682 } else { /* scall == MAT_REUSE_MATRIX */ 9683 PetscCall(MatProductReplaceMats(A,P,NULL,*C)); 9684 } 9685 9686 PetscCall(MatProductNumeric(*C)); 9687 if (A->symmetric) { 9688 if (A->spd) { 9689 PetscCall(MatSetOption(*C,MAT_SPD,PETSC_TRUE)); 9690 } else { 9691 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9692 } 9693 } 9694 PetscFunctionReturn(0); 9695 } 9696 9697 /*@ 9698 MatRARt - Creates the matrix product C = R * A * R^T 9699 9700 Neighbor-wise Collective on Mat 9701 9702 Input Parameters: 9703 + A - the matrix 9704 . R - the projection matrix 9705 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9706 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9707 if the result is a dense matrix this is irrelevant 9708 9709 Output Parameters: 9710 . C - the product matrix 9711 9712 Notes: 9713 C will be created and must be destroyed by the user with MatDestroy(). 9714 9715 This routine is currently only implemented for pairs of AIJ matrices and classes 9716 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9717 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9718 We recommend using MatPtAP(). 9719 9720 Level: intermediate 9721 9722 .seealso: `MatMatMult()`, `MatPtAP()` 9723 @*/ 9724 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9725 { 9726 PetscFunctionBegin; 9727 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*C,5); 9728 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9729 9730 if (scall == MAT_INITIAL_MATRIX) { 9731 PetscCall(MatProductCreate(A,R,NULL,C)); 9732 PetscCall(MatProductSetType(*C,MATPRODUCT_RARt)); 9733 PetscCall(MatProductSetAlgorithm(*C,"default")); 9734 PetscCall(MatProductSetFill(*C,fill)); 9735 9736 (*C)->product->api_user = PETSC_TRUE; 9737 PetscCall(MatProductSetFromOptions(*C)); 9738 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); 9739 PetscCall(MatProductSymbolic(*C)); 9740 } else { /* scall == MAT_REUSE_MATRIX */ 9741 PetscCall(MatProductReplaceMats(A,R,NULL,*C)); 9742 } 9743 9744 PetscCall(MatProductNumeric(*C)); 9745 if (A->symmetric_set && A->symmetric) { 9746 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9747 } 9748 PetscFunctionReturn(0); 9749 } 9750 9751 static PetscErrorCode MatProduct_Private(Mat A,Mat B,MatReuse scall,PetscReal fill,MatProductType ptype, Mat *C) 9752 { 9753 PetscFunctionBegin; 9754 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9755 9756 if (scall == MAT_INITIAL_MATRIX) { 9757 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_INITIAL_MATRIX and product type %s\n",MatProductTypes[ptype])); 9758 PetscCall(MatProductCreate(A,B,NULL,C)); 9759 PetscCall(MatProductSetType(*C,ptype)); 9760 PetscCall(MatProductSetAlgorithm(*C,MATPRODUCTALGORITHMDEFAULT)); 9761 PetscCall(MatProductSetFill(*C,fill)); 9762 9763 (*C)->product->api_user = PETSC_TRUE; 9764 PetscCall(MatProductSetFromOptions(*C)); 9765 PetscCall(MatProductSymbolic(*C)); 9766 } else { /* scall == MAT_REUSE_MATRIX */ 9767 Mat_Product *product = (*C)->product; 9768 PetscBool isdense; 9769 9770 PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)(*C),&isdense,MATSEQDENSE,MATMPIDENSE,"")); 9771 if (isdense && product && product->type != ptype) { 9772 PetscCall(MatProductClear(*C)); 9773 product = NULL; 9774 } 9775 PetscCall(PetscInfo(A,"Calling MatProduct API with MAT_REUSE_MATRIX %s product present and product type %s\n",product ? "with" : "without",MatProductTypes[ptype])); 9776 if (!product) { /* user provide the dense matrix *C without calling MatProductCreate() or reusing it from previous calls */ 9777 if (isdense) { 9778 PetscCall(MatProductCreate_Private(A,B,NULL,*C)); 9779 product = (*C)->product; 9780 product->fill = fill; 9781 product->api_user = PETSC_TRUE; 9782 product->clear = PETSC_TRUE; 9783 9784 PetscCall(MatProductSetType(*C,ptype)); 9785 PetscCall(MatProductSetFromOptions(*C)); 9786 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); 9787 PetscCall(MatProductSymbolic(*C)); 9788 } else SETERRQ(PetscObjectComm((PetscObject)(*C)),PETSC_ERR_SUP,"Call MatProductCreate() first"); 9789 } else { /* user may change input matrices A or B when REUSE */ 9790 PetscCall(MatProductReplaceMats(A,B,NULL,*C)); 9791 } 9792 } 9793 PetscCall(MatProductNumeric(*C)); 9794 PetscFunctionReturn(0); 9795 } 9796 9797 /*@ 9798 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9799 9800 Neighbor-wise Collective on Mat 9801 9802 Input Parameters: 9803 + A - the left matrix 9804 . B - the right matrix 9805 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9806 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9807 if the result is a dense matrix this is irrelevant 9808 9809 Output Parameters: 9810 . C - the product matrix 9811 9812 Notes: 9813 Unless scall is MAT_REUSE_MATRIX C will be created. 9814 9815 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 9816 call to this function with MAT_INITIAL_MATRIX. 9817 9818 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. 9819 9820 If you have many matrices with the same non-zero structure to multiply, you should use MatProductCreate()/MatProductSymbolic()/MatProductReplaceMats(), and call MatProductNumeric() repeatedly. 9821 9822 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. 9823 9824 Example of Usage: 9825 .vb 9826 MatProductCreate(A,B,NULL,&C); 9827 MatProductSetType(C,MATPRODUCT_AB); 9828 MatProductSymbolic(C); 9829 MatProductNumeric(C); // compute C=A * B 9830 MatProductReplaceMats(A1,B1,NULL,C); // compute C=A1 * B1 9831 MatProductNumeric(C); 9832 MatProductReplaceMats(A2,NULL,NULL,C); // compute C=A2 * B1 9833 MatProductNumeric(C); 9834 .ve 9835 9836 Level: intermediate 9837 9838 .seealso: `MatTransposeMatMult()`, `MatMatTransposeMult()`, `MatPtAP()`, `MatProductCreate()`, `MatProductSymbolic()`, `MatProductReplaceMats()`, `MatProductNumeric()` 9839 @*/ 9840 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9841 { 9842 PetscFunctionBegin; 9843 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AB,C)); 9844 PetscFunctionReturn(0); 9845 } 9846 9847 /*@ 9848 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9849 9850 Neighbor-wise Collective on Mat 9851 9852 Input Parameters: 9853 + A - the left matrix 9854 . B - the right matrix 9855 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9856 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9857 9858 Output Parameters: 9859 . C - the product matrix 9860 9861 Notes: 9862 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9863 9864 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9865 9866 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9867 actually needed. 9868 9869 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9870 and for pairs of MPIDense matrices. 9871 9872 Options Database Keys: 9873 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorithms for MPIDense matrices: the 9874 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9875 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9876 9877 Level: intermediate 9878 9879 .seealso: `MatMatMult()`, `MatTransposeMatMult()` `MatPtAP()` 9880 @*/ 9881 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9882 { 9883 PetscFunctionBegin; 9884 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_ABt,C)); 9885 if (A == B) { 9886 PetscCall(MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE)); 9887 } 9888 PetscFunctionReturn(0); 9889 } 9890 9891 /*@ 9892 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9893 9894 Neighbor-wise Collective on Mat 9895 9896 Input Parameters: 9897 + A - the left matrix 9898 . B - the right matrix 9899 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9900 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9901 9902 Output Parameters: 9903 . C - the product matrix 9904 9905 Notes: 9906 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9907 9908 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call. 9909 9910 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9911 actually needed. 9912 9913 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9914 which inherit from SeqAIJ. C will be of the same type as the input matrices. 9915 9916 Level: intermediate 9917 9918 .seealso: `MatMatMult()`, `MatMatTransposeMult()`, `MatPtAP()` 9919 @*/ 9920 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9921 { 9922 PetscFunctionBegin; 9923 PetscCall(MatProduct_Private(A,B,scall,fill,MATPRODUCT_AtB,C)); 9924 PetscFunctionReturn(0); 9925 } 9926 9927 /*@ 9928 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9929 9930 Neighbor-wise Collective on Mat 9931 9932 Input Parameters: 9933 + A - the left matrix 9934 . B - the middle matrix 9935 . C - the right matrix 9936 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9937 - 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 9938 if the result is a dense matrix this is irrelevant 9939 9940 Output Parameters: 9941 . D - the product matrix 9942 9943 Notes: 9944 Unless scall is MAT_REUSE_MATRIX D will be created. 9945 9946 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9947 9948 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9949 actually needed. 9950 9951 If you have many matrices with the same non-zero structure to multiply, you 9952 should use MAT_REUSE_MATRIX in all calls but the first 9953 9954 Level: intermediate 9955 9956 .seealso: `MatMatMult`, `MatPtAP()`, `MatMatTransposeMult()`, `MatTransposeMatMult()` 9957 @*/ 9958 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9959 { 9960 PetscFunctionBegin; 9961 if (scall == MAT_REUSE_MATRIX) MatCheckProduct(*D,6); 9962 PetscCheck(scall != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9963 9964 if (scall == MAT_INITIAL_MATRIX) { 9965 PetscCall(MatProductCreate(A,B,C,D)); 9966 PetscCall(MatProductSetType(*D,MATPRODUCT_ABC)); 9967 PetscCall(MatProductSetAlgorithm(*D,"default")); 9968 PetscCall(MatProductSetFill(*D,fill)); 9969 9970 (*D)->product->api_user = PETSC_TRUE; 9971 PetscCall(MatProductSetFromOptions(*D)); 9972 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); 9973 PetscCall(MatProductSymbolic(*D)); 9974 } else { /* user may change input matrices when REUSE */ 9975 PetscCall(MatProductReplaceMats(A,B,C,*D)); 9976 } 9977 PetscCall(MatProductNumeric(*D)); 9978 PetscFunctionReturn(0); 9979 } 9980 9981 /*@ 9982 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9983 9984 Collective on Mat 9985 9986 Input Parameters: 9987 + mat - the matrix 9988 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9989 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 9990 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9991 9992 Output Parameter: 9993 . matredundant - redundant matrix 9994 9995 Notes: 9996 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9997 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9998 9999 This routine creates the duplicated matrices in the subcommunicators; you should NOT create them before 10000 calling it. 10001 10002 Level: advanced 10003 10004 .seealso: `MatDestroy()` 10005 @*/ 10006 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10007 { 10008 MPI_Comm comm; 10009 PetscMPIInt size; 10010 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10011 Mat_Redundant *redund=NULL; 10012 PetscSubcomm psubcomm=NULL; 10013 MPI_Comm subcomm_in=subcomm; 10014 Mat *matseq; 10015 IS isrow,iscol; 10016 PetscBool newsubcomm=PETSC_FALSE; 10017 10018 PetscFunctionBegin; 10019 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10020 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10021 PetscValidPointer(*matredundant,5); 10022 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10023 } 10024 10025 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10026 if (size == 1 || nsubcomm == 1) { 10027 if (reuse == MAT_INITIAL_MATRIX) { 10028 PetscCall(MatDuplicate(mat,MAT_COPY_VALUES,matredundant)); 10029 } else { 10030 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"); 10031 PetscCall(MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN)); 10032 } 10033 PetscFunctionReturn(0); 10034 } 10035 10036 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10037 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10038 MatCheckPreallocated(mat,1); 10039 10040 PetscCall(PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0)); 10041 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10042 /* create psubcomm, then get subcomm */ 10043 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10044 PetscCallMPI(MPI_Comm_size(comm,&size)); 10045 PetscCheck(nsubcomm >= 1 && nsubcomm <= size,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %d",size); 10046 10047 PetscCall(PetscSubcommCreate(comm,&psubcomm)); 10048 PetscCall(PetscSubcommSetNumber(psubcomm,nsubcomm)); 10049 PetscCall(PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS)); 10050 PetscCall(PetscSubcommSetFromOptions(psubcomm)); 10051 PetscCall(PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL)); 10052 newsubcomm = PETSC_TRUE; 10053 PetscCall(PetscSubcommDestroy(&psubcomm)); 10054 } 10055 10056 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10057 if (reuse == MAT_INITIAL_MATRIX) { 10058 mloc_sub = PETSC_DECIDE; 10059 nloc_sub = PETSC_DECIDE; 10060 if (bs < 1) { 10061 PetscCall(PetscSplitOwnership(subcomm,&mloc_sub,&M)); 10062 PetscCall(PetscSplitOwnership(subcomm,&nloc_sub,&N)); 10063 } else { 10064 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M)); 10065 PetscCall(PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N)); 10066 } 10067 PetscCallMPI(MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm)); 10068 rstart = rend - mloc_sub; 10069 PetscCall(ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow)); 10070 PetscCall(ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol)); 10071 } else { /* reuse == MAT_REUSE_MATRIX */ 10072 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"); 10073 /* retrieve subcomm */ 10074 PetscCall(PetscObjectGetComm((PetscObject)(*matredundant),&subcomm)); 10075 redund = (*matredundant)->redundant; 10076 isrow = redund->isrow; 10077 iscol = redund->iscol; 10078 matseq = redund->matseq; 10079 } 10080 PetscCall(MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq)); 10081 10082 /* get matredundant over subcomm */ 10083 if (reuse == MAT_INITIAL_MATRIX) { 10084 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant)); 10085 10086 /* create a supporting struct and attach it to C for reuse */ 10087 PetscCall(PetscNewLog(*matredundant,&redund)); 10088 (*matredundant)->redundant = redund; 10089 redund->isrow = isrow; 10090 redund->iscol = iscol; 10091 redund->matseq = matseq; 10092 if (newsubcomm) { 10093 redund->subcomm = subcomm; 10094 } else { 10095 redund->subcomm = MPI_COMM_NULL; 10096 } 10097 } else { 10098 PetscCall(MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant)); 10099 } 10100 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 10101 if (matseq[0]->boundtocpu && matseq[0]->bindingpropagates) { 10102 PetscCall(MatBindToCPU(*matredundant,PETSC_TRUE)); 10103 PetscCall(MatSetBindingPropagates(*matredundant,PETSC_TRUE)); 10104 } 10105 #endif 10106 PetscCall(PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0)); 10107 PetscFunctionReturn(0); 10108 } 10109 10110 /*@C 10111 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10112 a given 'mat' object. Each submatrix can span multiple procs. 10113 10114 Collective on Mat 10115 10116 Input Parameters: 10117 + mat - the matrix 10118 . subcomm - the subcommunicator obtained by com_split(comm) 10119 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10120 10121 Output Parameter: 10122 . subMat - 'parallel submatrices each spans a given subcomm 10123 10124 Notes: 10125 The submatrix partition across processors is dictated by 'subComm' a 10126 communicator obtained by MPI_comm_split(). The subComm 10127 is not restriced to be grouped with consecutive original ranks. 10128 10129 Due the MPI_Comm_split() usage, the parallel layout of the submatrices 10130 map directly to the layout of the original matrix [wrt the local 10131 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10132 into the 'DiagonalMat' of the subMat, hence it is used directly from 10133 the subMat. However the offDiagMat looses some columns - and this is 10134 reconstructed with MatSetValues() 10135 10136 Level: advanced 10137 10138 .seealso: `MatCreateSubMatrices()` 10139 @*/ 10140 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10141 { 10142 PetscMPIInt commsize,subCommSize; 10143 10144 PetscFunctionBegin; 10145 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize)); 10146 PetscCallMPI(MPI_Comm_size(subComm,&subCommSize)); 10147 PetscCheck(subCommSize <= commsize,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %d < SubCommZize %d",commsize,subCommSize); 10148 10149 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"); 10150 PetscCall(PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0)); 10151 PetscCall((*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat)); 10152 PetscCall(PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0)); 10153 PetscFunctionReturn(0); 10154 } 10155 10156 /*@ 10157 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10158 10159 Not Collective 10160 10161 Input Parameters: 10162 + mat - matrix to extract local submatrix from 10163 . isrow - local row indices for submatrix 10164 - iscol - local column indices for submatrix 10165 10166 Output Parameter: 10167 . submat - the submatrix 10168 10169 Level: intermediate 10170 10171 Notes: 10172 The submat should be returned with MatRestoreLocalSubMatrix(). 10173 10174 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10175 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10176 10177 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10178 MatSetValuesBlockedLocal() will also be implemented. 10179 10180 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10181 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10182 10183 .seealso: `MatRestoreLocalSubMatrix()`, `MatCreateLocalRef()`, `MatSetLocalToGlobalMapping()` 10184 @*/ 10185 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10186 { 10187 PetscFunctionBegin; 10188 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10189 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10190 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10191 PetscCheckSameComm(isrow,2,iscol,3); 10192 PetscValidPointer(submat,4); 10193 PetscCheck(mat->rmap->mapping,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10194 10195 if (mat->ops->getlocalsubmatrix) { 10196 PetscCall((*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat)); 10197 } else { 10198 PetscCall(MatCreateLocalRef(mat,isrow,iscol,submat)); 10199 } 10200 PetscFunctionReturn(0); 10201 } 10202 10203 /*@ 10204 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10205 10206 Not Collective 10207 10208 Input Parameters: 10209 + mat - matrix to extract local submatrix from 10210 . isrow - local row indices for submatrix 10211 . iscol - local column indices for submatrix 10212 - submat - the submatrix 10213 10214 Level: intermediate 10215 10216 .seealso: `MatGetLocalSubMatrix()` 10217 @*/ 10218 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10219 { 10220 PetscFunctionBegin; 10221 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10222 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10223 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10224 PetscCheckSameComm(isrow,2,iscol,3); 10225 PetscValidPointer(submat,4); 10226 if (*submat) { 10227 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10228 } 10229 10230 if (mat->ops->restorelocalsubmatrix) { 10231 PetscCall((*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat)); 10232 } else { 10233 PetscCall(MatDestroy(submat)); 10234 } 10235 *submat = NULL; 10236 PetscFunctionReturn(0); 10237 } 10238 10239 /* --------------------------------------------------------*/ 10240 /*@ 10241 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10242 10243 Collective on Mat 10244 10245 Input Parameter: 10246 . mat - the matrix 10247 10248 Output Parameter: 10249 . is - if any rows have zero diagonals this contains the list of them 10250 10251 Level: developer 10252 10253 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10254 @*/ 10255 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10256 { 10257 PetscFunctionBegin; 10258 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10259 PetscValidType(mat,1); 10260 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10261 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10262 10263 if (!mat->ops->findzerodiagonals) { 10264 Vec diag; 10265 const PetscScalar *a; 10266 PetscInt *rows; 10267 PetscInt rStart, rEnd, r, nrow = 0; 10268 10269 PetscCall(MatCreateVecs(mat, &diag, NULL)); 10270 PetscCall(MatGetDiagonal(mat, diag)); 10271 PetscCall(MatGetOwnershipRange(mat, &rStart, &rEnd)); 10272 PetscCall(VecGetArrayRead(diag, &a)); 10273 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10274 PetscCall(PetscMalloc1(nrow, &rows)); 10275 nrow = 0; 10276 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10277 PetscCall(VecRestoreArrayRead(diag, &a)); 10278 PetscCall(VecDestroy(&diag)); 10279 PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is)); 10280 } else { 10281 PetscCall((*mat->ops->findzerodiagonals)(mat, is)); 10282 } 10283 PetscFunctionReturn(0); 10284 } 10285 10286 /*@ 10287 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10288 10289 Collective on Mat 10290 10291 Input Parameter: 10292 . mat - the matrix 10293 10294 Output Parameter: 10295 . is - contains the list of rows with off block diagonal entries 10296 10297 Level: developer 10298 10299 .seealso: `MatMultTranspose()`, `MatMultAdd()`, `MatMultTransposeAdd()` 10300 @*/ 10301 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10302 { 10303 PetscFunctionBegin; 10304 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10305 PetscValidType(mat,1); 10306 PetscCheck(mat->assembled,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10307 PetscCheck(!mat->factortype,PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10308 10309 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); 10310 PetscCall((*mat->ops->findoffblockdiagonalentries)(mat,is)); 10311 PetscFunctionReturn(0); 10312 } 10313 10314 /*@C 10315 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10316 10317 Collective on Mat 10318 10319 Input Parameters: 10320 . mat - the matrix 10321 10322 Output Parameters: 10323 . values - the block inverses in column major order (FORTRAN-like) 10324 10325 Note: 10326 The size of the blocks is determined by the block size of the matrix. 10327 10328 Fortran Note: 10329 This routine is not available from Fortran. 10330 10331 Level: advanced 10332 10333 .seealso: `MatInvertVariableBlockEnvelope()`, `MatInvertBlockDiagonalMat()` 10334 @*/ 10335 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10336 { 10337 PetscFunctionBegin; 10338 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10339 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10340 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10341 PetscCheck(mat->ops->invertblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10342 PetscCall((*mat->ops->invertblockdiagonal)(mat,values)); 10343 PetscFunctionReturn(0); 10344 } 10345 10346 /*@C 10347 MatInvertVariableBlockDiagonal - Inverts the point block diagonal entries. 10348 10349 Collective on Mat 10350 10351 Input Parameters: 10352 + mat - the matrix 10353 . nblocks - the number of blocks on the process, set with MatSetVariableBlockSizes() 10354 - bsizes - the size of each block on the process, set with MatSetVariableBlockSizes() 10355 10356 Output Parameters: 10357 . values - the block inverses in column major order (FORTRAN-like) 10358 10359 Note: 10360 This routine is not available from Fortran. 10361 10362 Level: advanced 10363 10364 .seealso: `MatInvertBlockDiagonal()`, `MatSetVariableBlockSizes()`, `MatInvertVariableBlockEnvelope()` 10365 @*/ 10366 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10367 { 10368 PetscFunctionBegin; 10369 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10370 PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10371 PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10372 PetscCheck(mat->ops->invertvariableblockdiagonal,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10373 PetscCall((*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values)); 10374 PetscFunctionReturn(0); 10375 } 10376 10377 /*@ 10378 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10379 10380 Collective on Mat 10381 10382 Input Parameters: 10383 . A - the matrix 10384 10385 Output Parameters: 10386 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10387 10388 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10389 10390 Level: advanced 10391 10392 .seealso: `MatInvertBlockDiagonal()` 10393 @*/ 10394 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10395 { 10396 const PetscScalar *vals; 10397 PetscInt *dnnz; 10398 PetscInt m,rstart,rend,bs,i,j; 10399 10400 PetscFunctionBegin; 10401 PetscCall(MatInvertBlockDiagonal(A,&vals)); 10402 PetscCall(MatGetBlockSize(A,&bs)); 10403 PetscCall(MatGetLocalSize(A,&m,NULL)); 10404 PetscCall(MatSetLayouts(C,A->rmap,A->cmap)); 10405 PetscCall(PetscMalloc1(m/bs,&dnnz)); 10406 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10407 PetscCall(MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL)); 10408 PetscCall(PetscFree(dnnz)); 10409 PetscCall(MatGetOwnershipRange(C,&rstart,&rend)); 10410 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE)); 10411 for (i = rstart/bs; i < rend/bs; i++) { 10412 PetscCall(MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES)); 10413 } 10414 PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY)); 10415 PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY)); 10416 PetscCall(MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE)); 10417 PetscFunctionReturn(0); 10418 } 10419 10420 /*@C 10421 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10422 via MatTransposeColoringCreate(). 10423 10424 Collective on MatTransposeColoring 10425 10426 Input Parameter: 10427 . c - coloring context 10428 10429 Level: intermediate 10430 10431 .seealso: `MatTransposeColoringCreate()` 10432 @*/ 10433 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10434 { 10435 MatTransposeColoring matcolor=*c; 10436 10437 PetscFunctionBegin; 10438 if (!matcolor) PetscFunctionReturn(0); 10439 if (--((PetscObject)matcolor)->refct > 0) {matcolor = NULL; PetscFunctionReturn(0);} 10440 10441 PetscCall(PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow)); 10442 PetscCall(PetscFree(matcolor->rows)); 10443 PetscCall(PetscFree(matcolor->den2sp)); 10444 PetscCall(PetscFree(matcolor->colorforcol)); 10445 PetscCall(PetscFree(matcolor->columns)); 10446 if (matcolor->brows>0) PetscCall(PetscFree(matcolor->lstart)); 10447 PetscCall(PetscHeaderDestroy(c)); 10448 PetscFunctionReturn(0); 10449 } 10450 10451 /*@C 10452 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10453 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10454 MatTransposeColoring to sparse B. 10455 10456 Collective on MatTransposeColoring 10457 10458 Input Parameters: 10459 + B - sparse matrix B 10460 . Btdense - symbolic dense matrix B^T 10461 - coloring - coloring context created with MatTransposeColoringCreate() 10462 10463 Output Parameter: 10464 . Btdense - dense matrix B^T 10465 10466 Level: advanced 10467 10468 Notes: 10469 These are used internally for some implementations of MatRARt() 10470 10471 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplyDenToSp()` 10472 10473 @*/ 10474 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10475 { 10476 PetscFunctionBegin; 10477 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 10478 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,3); 10479 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10480 10481 PetscCheck(B->ops->transcoloringapplysptoden,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10482 PetscCall((B->ops->transcoloringapplysptoden)(coloring,B,Btdense)); 10483 PetscFunctionReturn(0); 10484 } 10485 10486 /*@C 10487 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10488 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10489 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10490 Csp from Cden. 10491 10492 Collective on MatTransposeColoring 10493 10494 Input Parameters: 10495 + coloring - coloring context created with MatTransposeColoringCreate() 10496 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10497 10498 Output Parameter: 10499 . Csp - sparse matrix 10500 10501 Level: advanced 10502 10503 Notes: 10504 These are used internally for some implementations of MatRARt() 10505 10506 .seealso: `MatTransposeColoringCreate()`, `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()` 10507 10508 @*/ 10509 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10510 { 10511 PetscFunctionBegin; 10512 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10513 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10514 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10515 10516 PetscCheck(Csp->ops->transcoloringapplydentosp,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10517 PetscCall((Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp)); 10518 PetscCall(MatAssemblyBegin(Csp,MAT_FINAL_ASSEMBLY)); 10519 PetscCall(MatAssemblyEnd(Csp,MAT_FINAL_ASSEMBLY)); 10520 PetscFunctionReturn(0); 10521 } 10522 10523 /*@C 10524 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10525 10526 Collective on Mat 10527 10528 Input Parameters: 10529 + mat - the matrix product C 10530 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10531 10532 Output Parameter: 10533 . color - the new coloring context 10534 10535 Level: intermediate 10536 10537 .seealso: `MatTransposeColoringDestroy()`, `MatTransColoringApplySpToDen()`, 10538 `MatTransColoringApplyDenToSp()` 10539 @*/ 10540 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10541 { 10542 MatTransposeColoring c; 10543 MPI_Comm comm; 10544 10545 PetscFunctionBegin; 10546 PetscCall(PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0)); 10547 PetscCall(PetscObjectGetComm((PetscObject)mat,&comm)); 10548 PetscCall(PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL)); 10549 10550 c->ctype = iscoloring->ctype; 10551 if (mat->ops->transposecoloringcreate) { 10552 PetscCall((*mat->ops->transposecoloringcreate)(mat,iscoloring,c)); 10553 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 10554 10555 *color = c; 10556 PetscCall(PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0)); 10557 PetscFunctionReturn(0); 10558 } 10559 10560 /*@ 10561 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10562 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10563 same, otherwise it will be larger 10564 10565 Not Collective 10566 10567 Input Parameter: 10568 . A - the matrix 10569 10570 Output Parameter: 10571 . state - the current state 10572 10573 Notes: 10574 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10575 different matrices 10576 10577 Level: intermediate 10578 10579 @*/ 10580 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10581 { 10582 PetscFunctionBegin; 10583 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10584 *state = mat->nonzerostate; 10585 PetscFunctionReturn(0); 10586 } 10587 10588 /*@ 10589 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10590 matrices from each processor 10591 10592 Collective 10593 10594 Input Parameters: 10595 + comm - the communicators the parallel matrix will live on 10596 . seqmat - the input sequential matrices 10597 . n - number of local columns (or PETSC_DECIDE) 10598 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10599 10600 Output Parameter: 10601 . mpimat - the parallel matrix generated 10602 10603 Level: advanced 10604 10605 Notes: 10606 The number of columns of the matrix in EACH processor MUST be the same. 10607 10608 @*/ 10609 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10610 { 10611 PetscMPIInt size; 10612 10613 PetscFunctionBegin; 10614 PetscCallMPI(MPI_Comm_size(comm,&size)); 10615 if (size == 1) { 10616 *mpimat = seqmat; 10617 // PetscCall(PetscObjectReference((PetscObject)seqmat)); 10618 PetscFunctionReturn(0); 10619 } 10620 10621 PetscCheck(seqmat->ops->creatempimatconcatenateseqmat,PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10622 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"); 10623 10624 PetscCall(PetscLogEventBegin(MAT_Merge,seqmat,0,0,0)); 10625 PetscCall((*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat)); 10626 PetscCall(PetscLogEventEnd(MAT_Merge,seqmat,0,0,0)); 10627 PetscFunctionReturn(0); 10628 } 10629 10630 /*@ 10631 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10632 ranks' ownership ranges. 10633 10634 Collective on A 10635 10636 Input Parameters: 10637 + A - the matrix to create subdomains from 10638 - N - requested number of subdomains 10639 10640 Output Parameters: 10641 + n - number of subdomains resulting on this rank 10642 - iss - IS list with indices of subdomains on this rank 10643 10644 Level: advanced 10645 10646 Notes: 10647 number of subdomains must be smaller than the communicator size 10648 @*/ 10649 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10650 { 10651 MPI_Comm comm,subcomm; 10652 PetscMPIInt size,rank,color; 10653 PetscInt rstart,rend,k; 10654 10655 PetscFunctionBegin; 10656 PetscCall(PetscObjectGetComm((PetscObject)A,&comm)); 10657 PetscCallMPI(MPI_Comm_size(comm,&size)); 10658 PetscCallMPI(MPI_Comm_rank(comm,&rank)); 10659 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); 10660 *n = 1; 10661 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10662 color = rank/k; 10663 PetscCallMPI(MPI_Comm_split(comm,color,rank,&subcomm)); 10664 PetscCall(PetscMalloc1(1,iss)); 10665 PetscCall(MatGetOwnershipRange(A,&rstart,&rend)); 10666 PetscCall(ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0])); 10667 PetscCallMPI(MPI_Comm_free(&subcomm)); 10668 PetscFunctionReturn(0); 10669 } 10670 10671 /*@ 10672 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10673 10674 If the interpolation and restriction operators are the same, uses MatPtAP. 10675 If they are not the same, use MatMatMatMult. 10676 10677 Once the coarse grid problem is constructed, correct for interpolation operators 10678 that are not of full rank, which can legitimately happen in the case of non-nested 10679 geometric multigrid. 10680 10681 Input Parameters: 10682 + restrct - restriction operator 10683 . dA - fine grid matrix 10684 . interpolate - interpolation operator 10685 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10686 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10687 10688 Output Parameters: 10689 . A - the Galerkin coarse matrix 10690 10691 Options Database Key: 10692 . -pc_mg_galerkin <both,pmat,mat,none> - for what matrices the Galerkin process should be used 10693 10694 Level: developer 10695 10696 .seealso: `MatPtAP()`, `MatMatMatMult()` 10697 @*/ 10698 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10699 { 10700 IS zerorows; 10701 Vec diag; 10702 10703 PetscFunctionBegin; 10704 PetscCheck(reuse != MAT_INPLACE_MATRIX,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10705 /* Construct the coarse grid matrix */ 10706 if (interpolate == restrct) { 10707 PetscCall(MatPtAP(dA,interpolate,reuse,fill,A)); 10708 } else { 10709 PetscCall(MatMatMatMult(restrct,dA,interpolate,reuse,fill,A)); 10710 } 10711 10712 /* If the interpolation matrix is not of full rank, A will have zero rows. 10713 This can legitimately happen in the case of non-nested geometric multigrid. 10714 In that event, we set the rows of the matrix to the rows of the identity, 10715 ignoring the equations (as the RHS will also be zero). */ 10716 10717 PetscCall(MatFindZeroRows(*A, &zerorows)); 10718 10719 if (zerorows != NULL) { /* if there are any zero rows */ 10720 PetscCall(MatCreateVecs(*A, &diag, NULL)); 10721 PetscCall(MatGetDiagonal(*A, diag)); 10722 PetscCall(VecISSet(diag, zerorows, 1.0)); 10723 PetscCall(MatDiagonalSet(*A, diag, INSERT_VALUES)); 10724 PetscCall(VecDestroy(&diag)); 10725 PetscCall(ISDestroy(&zerorows)); 10726 } 10727 PetscFunctionReturn(0); 10728 } 10729 10730 /*@C 10731 MatSetOperation - Allows user to set a matrix operation for any matrix type 10732 10733 Logically Collective on Mat 10734 10735 Input Parameters: 10736 + mat - the matrix 10737 . op - the name of the operation 10738 - f - the function that provides the operation 10739 10740 Level: developer 10741 10742 Usage: 10743 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10744 $ PetscCall(MatCreateXXX(comm,...&A); 10745 $ PetscCall(MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10746 10747 Notes: 10748 See the file include/petscmat.h for a complete list of matrix 10749 operations, which all have the form MATOP_<OPERATION>, where 10750 <OPERATION> is the name (in all capital letters) of the 10751 user interface routine (e.g., MatMult() -> MATOP_MULT). 10752 10753 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10754 sequence as the usual matrix interface routines, since they 10755 are intended to be accessed via the usual matrix interface 10756 routines, e.g., 10757 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10758 10759 In particular each function MUST return an error code of 0 on success and 10760 nonzero on failure. 10761 10762 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10763 10764 .seealso: `MatGetOperation()`, `MatCreateShell()`, `MatShellSetContext()`, `MatShellSetOperation()` 10765 @*/ 10766 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10767 { 10768 PetscFunctionBegin; 10769 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10770 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10771 mat->ops->viewnative = mat->ops->view; 10772 } 10773 (((void(**)(void))mat->ops)[op]) = f; 10774 PetscFunctionReturn(0); 10775 } 10776 10777 /*@C 10778 MatGetOperation - Gets a matrix operation for any matrix type. 10779 10780 Not Collective 10781 10782 Input Parameters: 10783 + mat - the matrix 10784 - op - the name of the operation 10785 10786 Output Parameter: 10787 . f - the function that provides the operation 10788 10789 Level: developer 10790 10791 Usage: 10792 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10793 $ MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10794 10795 Notes: 10796 See the file include/petscmat.h for a complete list of matrix 10797 operations, which all have the form MATOP_<OPERATION>, where 10798 <OPERATION> is the name (in all capital letters) of the 10799 user interface routine (e.g., MatMult() -> MATOP_MULT). 10800 10801 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10802 10803 .seealso: `MatSetOperation()`, `MatCreateShell()`, `MatShellGetContext()`, `MatShellGetOperation()` 10804 @*/ 10805 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10806 { 10807 PetscFunctionBegin; 10808 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10809 *f = (((void (**)(void))mat->ops)[op]); 10810 PetscFunctionReturn(0); 10811 } 10812 10813 /*@ 10814 MatHasOperation - Determines whether the given matrix supports the particular 10815 operation. 10816 10817 Not Collective 10818 10819 Input Parameters: 10820 + mat - the matrix 10821 - op - the operation, for example, MATOP_GET_DIAGONAL 10822 10823 Output Parameter: 10824 . has - either PETSC_TRUE or PETSC_FALSE 10825 10826 Level: advanced 10827 10828 Notes: 10829 See the file include/petscmat.h for a complete list of matrix 10830 operations, which all have the form MATOP_<OPERATION>, where 10831 <OPERATION> is the name (in all capital letters) of the 10832 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10833 10834 .seealso: `MatCreateShell()` 10835 @*/ 10836 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10837 { 10838 PetscFunctionBegin; 10839 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10840 PetscValidBoolPointer(has,3); 10841 if (mat->ops->hasoperation) { 10842 PetscCall((*mat->ops->hasoperation)(mat,op,has)); 10843 } else { 10844 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10845 else { 10846 *has = PETSC_FALSE; 10847 if (op == MATOP_CREATE_SUBMATRIX) { 10848 PetscMPIInt size; 10849 10850 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size)); 10851 if (size == 1) { 10852 PetscCall(MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has)); 10853 } 10854 } 10855 } 10856 } 10857 PetscFunctionReturn(0); 10858 } 10859 10860 /*@ 10861 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10862 of the matrix are congruent 10863 10864 Collective on mat 10865 10866 Input Parameters: 10867 . mat - the matrix 10868 10869 Output Parameter: 10870 . cong - either PETSC_TRUE or PETSC_FALSE 10871 10872 Level: beginner 10873 10874 Notes: 10875 10876 .seealso: `MatCreate()`, `MatSetSizes()` 10877 @*/ 10878 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 10879 { 10880 PetscFunctionBegin; 10881 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10882 PetscValidType(mat,1); 10883 PetscValidBoolPointer(cong,2); 10884 if (!mat->rmap || !mat->cmap) { 10885 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10886 PetscFunctionReturn(0); 10887 } 10888 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10889 PetscCall(PetscLayoutSetUp(mat->rmap)); 10890 PetscCall(PetscLayoutSetUp(mat->cmap)); 10891 PetscCall(PetscLayoutCompare(mat->rmap,mat->cmap,cong)); 10892 if (*cong) mat->congruentlayouts = 1; 10893 else mat->congruentlayouts = 0; 10894 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10895 PetscFunctionReturn(0); 10896 } 10897 10898 PetscErrorCode MatSetInf(Mat A) 10899 { 10900 PetscFunctionBegin; 10901 PetscCheck(A->ops->setinf,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 10902 PetscCall((*A->ops->setinf)(A)); 10903 PetscFunctionReturn(0); 10904 } 10905 10906 /*C 10907 MatCreateGraph - create a scalar matrix, for use in graph algorithms 10908 10909 Collective on mat 10910 10911 Input Parameters: 10912 + A - the matrix 10913 - sym - PETSC_TRUE indicates that the graph will be symmetrized 10914 . scale - PETSC_TRUE indicates that the graph will be scaled with the diagonal 10915 10916 Output Parameter: 10917 . graph - the resulting graph 10918 10919 Level: advanced 10920 10921 Notes: 10922 10923 .seealso: `MatCreate()`, `MatFilter()` 10924 */ 10925 PETSC_EXTERN PetscErrorCode MatCreateGraph(Mat A, PetscBool sym, PetscBool scale, Mat *graph) 10926 { 10927 PetscFunctionBegin; 10928 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 10929 PetscValidType(A,1); 10930 PetscValidPointer(graph,3); 10931 PetscCheck(A->ops->creategraph,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 10932 PetscCall((*A->ops->creategraph)(A,sym,scale,graph)); 10933 PetscFunctionReturn(0); 10934 } 10935 10936 /*C 10937 MatFilter - filters a Mat values with an absolut value equal to or below a give threshold 10938 10939 Collective on mat 10940 10941 Input Parameter: 10942 . value - filter value - < 0: does nothing; == 0: removes only 0.0 entries; otherwise: removes entries <= value 10943 10944 Input/Output Parameter: 10945 . A - the Mat to filter in place 10946 10947 Level: advanced 10948 10949 Notes: 10950 10951 .seealso: `MatCreate()`, `MatCreateGraph()` 10952 */ 10953 PETSC_EXTERN PetscErrorCode MatFilter(Mat G,PetscReal value,Mat *F) 10954 { 10955 PetscFunctionBegin; 10956 PetscValidHeaderSpecific(G,MAT_CLASSID,1); 10957 PetscValidType(G,1); 10958 PetscValidPointer(F,3); 10959 if (value >= 0.0) { 10960 PetscCheck(G->ops->filter,PetscObjectComm((PetscObject)G),PETSC_ERR_SUP,"No support for this operation for this matrix type"); 10961 PetscCall((G->ops->filter)(G,value,F)); 10962 } 10963 PetscFunctionReturn(0); 10964 } 10965