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_MultConstrained, MAT_MultAdd, MAT_MultTranspose; 16 PetscLogEvent MAT_MultTransposeConstrained, 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_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 21 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 22 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat; 23 PetscLogEvent MAT_TransposeColoringCreate; 24 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 25 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 26 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 27 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 28 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 29 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 30 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols; 31 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 32 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 33 PetscLogEvent MAT_GetMultiProcBlock; 34 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch; 35 PetscLogEvent MAT_ViennaCLCopyToGPU; 36 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU; 37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 38 PetscLogEvent MAT_FactorFactS,MAT_FactorInvS; 39 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 40 41 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0}; 42 43 /*@ 44 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, 45 for sparse matrices that already have locations it fills the locations with random numbers 46 47 Logically Collective on Mat 48 49 Input Parameters: 50 + x - the matrix 51 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 52 it will create one internally. 53 54 Output Parameter: 55 . x - the matrix 56 57 Example of Usage: 58 .vb 59 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 60 MatSetRandom(x,rctx); 61 PetscRandomDestroy(rctx); 62 .ve 63 64 Level: intermediate 65 66 67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy() 68 @*/ 69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 70 { 71 PetscErrorCode ierr; 72 PetscRandom randObj = NULL; 73 74 PetscFunctionBegin; 75 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 76 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 77 PetscValidType(x,1); 78 79 if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 80 81 if (!rctx) { 82 MPI_Comm comm; 83 ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 84 ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr); 85 ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr); 86 rctx = randObj; 87 } 88 89 ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 90 ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr); 91 ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 92 93 ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 94 ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 95 ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr); 96 PetscFunctionReturn(0); 97 } 98 99 /*@ 100 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 101 102 Logically Collective on Mat 103 104 Input Parameters: 105 . mat - the factored matrix 106 107 Output Parameter: 108 + pivot - the pivot value computed 109 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 110 the share the matrix 111 112 Level: advanced 113 114 Notes: 115 This routine does not work for factorizations done with external packages. 116 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 117 118 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 119 120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 121 @*/ 122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 123 { 124 PetscFunctionBegin; 125 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 126 *pivot = mat->factorerror_zeropivot_value; 127 *row = mat->factorerror_zeropivot_row; 128 PetscFunctionReturn(0); 129 } 130 131 /*@ 132 MatFactorGetError - gets the error code from a factorization 133 134 Logically Collective on Mat 135 136 Input Parameters: 137 . mat - the factored matrix 138 139 Output Parameter: 140 . err - the error code 141 142 Level: advanced 143 144 Notes: 145 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 146 147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 148 @*/ 149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 150 { 151 PetscFunctionBegin; 152 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 153 *err = mat->factorerrortype; 154 PetscFunctionReturn(0); 155 } 156 157 /*@ 158 MatFactorClearError - clears the error code in a factorization 159 160 Logically Collective on Mat 161 162 Input Parameter: 163 . mat - the factored matrix 164 165 Level: developer 166 167 Notes: 168 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 169 170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot() 171 @*/ 172 PetscErrorCode MatFactorClearError(Mat mat) 173 { 174 PetscFunctionBegin; 175 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 176 mat->factorerrortype = MAT_FACTOR_NOERROR; 177 mat->factorerror_zeropivot_value = 0.0; 178 mat->factorerror_zeropivot_row = 0; 179 PetscFunctionReturn(0); 180 } 181 182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 183 { 184 PetscErrorCode ierr; 185 Vec r,l; 186 const PetscScalar *al; 187 PetscInt i,nz,gnz,N,n; 188 189 PetscFunctionBegin; 190 ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr); 191 if (!cols) { /* nonzero rows */ 192 ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 193 ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr); 194 ierr = VecSet(l,0.0);CHKERRQ(ierr); 195 ierr = VecSetRandom(r,NULL);CHKERRQ(ierr); 196 ierr = MatMult(mat,r,l);CHKERRQ(ierr); 197 ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr); 198 } else { /* nonzero columns */ 199 ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr); 200 ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr); 201 ierr = VecSet(r,0.0);CHKERRQ(ierr); 202 ierr = VecSetRandom(l,NULL);CHKERRQ(ierr); 203 ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr); 204 ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr); 205 } 206 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 207 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 208 ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 209 if (gnz != N) { 210 PetscInt *nzr; 211 ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr); 212 if (nz) { 213 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 214 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 215 } 216 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr); 217 } else *nonzero = NULL; 218 if (!cols) { /* nonzero rows */ 219 ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr); 220 } else { 221 ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr); 222 } 223 ierr = VecDestroy(&l);CHKERRQ(ierr); 224 ierr = VecDestroy(&r);CHKERRQ(ierr); 225 PetscFunctionReturn(0); 226 } 227 228 /*@ 229 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 230 231 Input Parameter: 232 . A - the matrix 233 234 Output Parameter: 235 . keptrows - the rows that are not completely zero 236 237 Notes: 238 keptrows is set to NULL if all rows are nonzero. 239 240 Level: intermediate 241 242 @*/ 243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 244 { 245 PetscErrorCode ierr; 246 247 PetscFunctionBegin; 248 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 249 PetscValidType(mat,1); 250 PetscValidPointer(keptrows,2); 251 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 252 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 253 if (!mat->ops->findnonzerorows) { 254 ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr); 255 } else { 256 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr); 257 } 258 PetscFunctionReturn(0); 259 } 260 261 /*@ 262 MatFindZeroRows - Locate all rows that are completely zero in the matrix 263 264 Input Parameter: 265 . A - the matrix 266 267 Output Parameter: 268 . zerorows - the rows that are completely zero 269 270 Notes: 271 zerorows is set to NULL if no rows are zero. 272 273 Level: intermediate 274 275 @*/ 276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 277 { 278 PetscErrorCode ierr; 279 IS keptrows; 280 PetscInt m, n; 281 282 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 283 PetscValidType(mat,1); 284 285 ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr); 286 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 287 In keeping with this convention, we set zerorows to NULL if there are no zero 288 rows. */ 289 if (keptrows == NULL) { 290 *zerorows = NULL; 291 } else { 292 ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr); 293 ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr); 294 ierr = ISDestroy(&keptrows);CHKERRQ(ierr); 295 } 296 PetscFunctionReturn(0); 297 } 298 299 /*@ 300 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 301 302 Not Collective 303 304 Input Parameters: 305 . A - the matrix 306 307 Output Parameters: 308 . a - the diagonal part (which is a SEQUENTIAL matrix) 309 310 Notes: 311 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 312 Use caution, as the reference count on the returned matrix is not incremented and it is used as 313 part of the containing MPI Mat's normal operation. 314 315 Level: advanced 316 317 @*/ 318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 319 { 320 PetscErrorCode ierr; 321 322 PetscFunctionBegin; 323 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 324 PetscValidType(A,1); 325 PetscValidPointer(a,3); 326 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 327 if (!A->ops->getdiagonalblock) { 328 PetscMPIInt size; 329 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 330 if (size == 1) { 331 *a = A; 332 PetscFunctionReturn(0); 333 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type"); 334 } 335 ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr); 336 PetscFunctionReturn(0); 337 } 338 339 /*@ 340 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 341 342 Collective on Mat 343 344 Input Parameters: 345 . mat - the matrix 346 347 Output Parameter: 348 . trace - the sum of the diagonal entries 349 350 Level: advanced 351 352 @*/ 353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 354 { 355 PetscErrorCode ierr; 356 Vec diag; 357 358 PetscFunctionBegin; 359 ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr); 360 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr); 361 ierr = VecSum(diag,trace);CHKERRQ(ierr); 362 ierr = VecDestroy(&diag);CHKERRQ(ierr); 363 PetscFunctionReturn(0); 364 } 365 366 /*@ 367 MatRealPart - Zeros out the imaginary part of the matrix 368 369 Logically Collective on Mat 370 371 Input Parameters: 372 . mat - the matrix 373 374 Level: advanced 375 376 377 .seealso: MatImaginaryPart() 378 @*/ 379 PetscErrorCode MatRealPart(Mat mat) 380 { 381 PetscErrorCode ierr; 382 383 PetscFunctionBegin; 384 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 385 PetscValidType(mat,1); 386 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 387 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 388 if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 389 MatCheckPreallocated(mat,1); 390 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr); 391 PetscFunctionReturn(0); 392 } 393 394 /*@C 395 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 396 397 Collective on Mat 398 399 Input Parameter: 400 . mat - the matrix 401 402 Output Parameters: 403 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 404 - ghosts - the global indices of the ghost points 405 406 Notes: 407 the nghosts and ghosts are suitable to pass into VecCreateGhost() 408 409 Level: advanced 410 411 @*/ 412 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 413 { 414 PetscErrorCode ierr; 415 416 PetscFunctionBegin; 417 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 418 PetscValidType(mat,1); 419 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 420 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 421 if (!mat->ops->getghosts) { 422 if (nghosts) *nghosts = 0; 423 if (ghosts) *ghosts = 0; 424 } else { 425 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr); 426 } 427 PetscFunctionReturn(0); 428 } 429 430 431 /*@ 432 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 433 434 Logically Collective on Mat 435 436 Input Parameters: 437 . mat - the matrix 438 439 Level: advanced 440 441 442 .seealso: MatRealPart() 443 @*/ 444 PetscErrorCode MatImaginaryPart(Mat mat) 445 { 446 PetscErrorCode ierr; 447 448 PetscFunctionBegin; 449 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 450 PetscValidType(mat,1); 451 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 452 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 453 if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 454 MatCheckPreallocated(mat,1); 455 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr); 456 PetscFunctionReturn(0); 457 } 458 459 /*@ 460 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 461 462 Not Collective 463 464 Input Parameter: 465 . mat - the matrix 466 467 Output Parameters: 468 + missing - is any diagonal missing 469 - dd - first diagonal entry that is missing (optional) on this process 470 471 Level: advanced 472 473 474 .seealso: MatRealPart() 475 @*/ 476 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 477 { 478 PetscErrorCode ierr; 479 480 PetscFunctionBegin; 481 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 482 PetscValidType(mat,1); 483 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 484 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 485 if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 486 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr); 487 PetscFunctionReturn(0); 488 } 489 490 /*@C 491 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 492 for each row that you get to ensure that your application does 493 not bleed memory. 494 495 Not Collective 496 497 Input Parameters: 498 + mat - the matrix 499 - row - the row to get 500 501 Output Parameters: 502 + ncols - if not NULL, the number of nonzeros in the row 503 . cols - if not NULL, the column numbers 504 - vals - if not NULL, the values 505 506 Notes: 507 This routine is provided for people who need to have direct access 508 to the structure of a matrix. We hope that we provide enough 509 high-level matrix routines that few users will need it. 510 511 MatGetRow() always returns 0-based column indices, regardless of 512 whether the internal representation is 0-based (default) or 1-based. 513 514 For better efficiency, set cols and/or vals to NULL if you do 515 not wish to extract these quantities. 516 517 The user can only examine the values extracted with MatGetRow(); 518 the values cannot be altered. To change the matrix entries, one 519 must use MatSetValues(). 520 521 You can only have one call to MatGetRow() outstanding for a particular 522 matrix at a time, per processor. MatGetRow() can only obtain rows 523 associated with the given processor, it cannot get rows from the 524 other processors; for that we suggest using MatCreateSubMatrices(), then 525 MatGetRow() on the submatrix. The row index passed to MatGetRow() 526 is in the global number of rows. 527 528 Fortran Notes: 529 The calling sequence from Fortran is 530 .vb 531 MatGetRow(matrix,row,ncols,cols,values,ierr) 532 Mat matrix (input) 533 integer row (input) 534 integer ncols (output) 535 integer cols(maxcols) (output) 536 double precision (or double complex) values(maxcols) output 537 .ve 538 where maxcols >= maximum nonzeros in any row of the matrix. 539 540 541 Caution: 542 Do not try to change the contents of the output arrays (cols and vals). 543 In some cases, this may corrupt the matrix. 544 545 Level: advanced 546 547 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal() 548 @*/ 549 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 550 { 551 PetscErrorCode ierr; 552 PetscInt incols; 553 554 PetscFunctionBegin; 555 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 556 PetscValidType(mat,1); 557 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 558 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 559 if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 560 MatCheckPreallocated(mat,1); 561 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 562 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr); 563 if (ncols) *ncols = incols; 564 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 565 PetscFunctionReturn(0); 566 } 567 568 /*@ 569 MatConjugate - replaces the matrix values with their complex conjugates 570 571 Logically Collective on Mat 572 573 Input Parameters: 574 . mat - the matrix 575 576 Level: advanced 577 578 .seealso: VecConjugate() 579 @*/ 580 PetscErrorCode MatConjugate(Mat mat) 581 { 582 #if defined(PETSC_USE_COMPLEX) 583 PetscErrorCode ierr; 584 585 PetscFunctionBegin; 586 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 587 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 588 if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov"); 589 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr); 590 #else 591 PetscFunctionBegin; 592 #endif 593 PetscFunctionReturn(0); 594 } 595 596 /*@C 597 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 598 599 Not Collective 600 601 Input Parameters: 602 + mat - the matrix 603 . row - the row to get 604 . ncols, cols - the number of nonzeros and their columns 605 - vals - if nonzero the column values 606 607 Notes: 608 This routine should be called after you have finished examining the entries. 609 610 This routine zeros out ncols, cols, and vals. This is to prevent accidental 611 us of the array after it has been restored. If you pass NULL, it will 612 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 613 614 Fortran Notes: 615 The calling sequence from Fortran is 616 .vb 617 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 618 Mat matrix (input) 619 integer row (input) 620 integer ncols (output) 621 integer cols(maxcols) (output) 622 double precision (or double complex) values(maxcols) output 623 .ve 624 Where maxcols >= maximum nonzeros in any row of the matrix. 625 626 In Fortran MatRestoreRow() MUST be called after MatGetRow() 627 before another call to MatGetRow() can be made. 628 629 Level: advanced 630 631 .seealso: MatGetRow() 632 @*/ 633 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 634 { 635 PetscErrorCode ierr; 636 637 PetscFunctionBegin; 638 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 639 if (ncols) PetscValidIntPointer(ncols,3); 640 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 641 if (!mat->ops->restorerow) PetscFunctionReturn(0); 642 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 643 if (ncols) *ncols = 0; 644 if (cols) *cols = NULL; 645 if (vals) *vals = NULL; 646 PetscFunctionReturn(0); 647 } 648 649 /*@ 650 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 651 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 652 653 Not Collective 654 655 Input Parameters: 656 . mat - the matrix 657 658 Notes: 659 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. 660 661 Level: advanced 662 663 .seealso: MatRestoreRowUpperTriangular() 664 @*/ 665 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 666 { 667 PetscErrorCode ierr; 668 669 PetscFunctionBegin; 670 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 671 PetscValidType(mat,1); 672 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 673 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 674 MatCheckPreallocated(mat,1); 675 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 676 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr); 677 PetscFunctionReturn(0); 678 } 679 680 /*@ 681 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 682 683 Not Collective 684 685 Input Parameters: 686 . mat - the matrix 687 688 Notes: 689 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 690 691 692 Level: advanced 693 694 .seealso: MatGetRowUpperTriangular() 695 @*/ 696 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 697 { 698 PetscErrorCode ierr; 699 700 PetscFunctionBegin; 701 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 702 PetscValidType(mat,1); 703 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 704 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 705 MatCheckPreallocated(mat,1); 706 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 707 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr); 708 PetscFunctionReturn(0); 709 } 710 711 /*@C 712 MatSetOptionsPrefix - Sets the prefix used for searching for all 713 Mat options in the database. 714 715 Logically Collective on Mat 716 717 Input Parameter: 718 + A - the Mat context 719 - prefix - the prefix to prepend to all option names 720 721 Notes: 722 A hyphen (-) must NOT be given at the beginning of the prefix name. 723 The first character of all runtime options is AUTOMATICALLY the hyphen. 724 725 Level: advanced 726 727 .seealso: MatSetFromOptions() 728 @*/ 729 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 730 { 731 PetscErrorCode ierr; 732 733 PetscFunctionBegin; 734 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 735 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 736 PetscFunctionReturn(0); 737 } 738 739 /*@C 740 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 741 Mat options in the database. 742 743 Logically Collective on Mat 744 745 Input Parameters: 746 + A - the Mat context 747 - prefix - the prefix to prepend to all option names 748 749 Notes: 750 A hyphen (-) must NOT be given at the beginning of the prefix name. 751 The first character of all runtime options is AUTOMATICALLY the hyphen. 752 753 Level: advanced 754 755 .seealso: MatGetOptionsPrefix() 756 @*/ 757 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 758 { 759 PetscErrorCode ierr; 760 761 PetscFunctionBegin; 762 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 763 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 764 PetscFunctionReturn(0); 765 } 766 767 /*@C 768 MatGetOptionsPrefix - Sets the prefix used for searching for all 769 Mat options in the database. 770 771 Not Collective 772 773 Input Parameter: 774 . A - the Mat context 775 776 Output Parameter: 777 . prefix - pointer to the prefix string used 778 779 Notes: 780 On the fortran side, the user should pass in a string 'prefix' of 781 sufficient length to hold the prefix. 782 783 Level: advanced 784 785 .seealso: MatAppendOptionsPrefix() 786 @*/ 787 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 788 { 789 PetscErrorCode ierr; 790 791 PetscFunctionBegin; 792 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 793 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 794 PetscFunctionReturn(0); 795 } 796 797 /*@ 798 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 799 800 Collective on Mat 801 802 Input Parameters: 803 . A - the Mat context 804 805 Notes: 806 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 807 Currently support MPIAIJ and SEQAIJ. 808 809 Level: beginner 810 811 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation() 812 @*/ 813 PetscErrorCode MatResetPreallocation(Mat A) 814 { 815 PetscErrorCode ierr; 816 817 PetscFunctionBegin; 818 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 819 PetscValidType(A,1); 820 ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr); 821 PetscFunctionReturn(0); 822 } 823 824 825 /*@ 826 MatSetUp - Sets up the internal matrix data structures for the later use. 827 828 Collective on Mat 829 830 Input Parameters: 831 . A - the Mat context 832 833 Notes: 834 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 835 836 If a suitable preallocation routine is used, this function does not need to be called. 837 838 See the Performance chapter of the PETSc users manual for how to preallocate matrices 839 840 Level: beginner 841 842 .seealso: MatCreate(), MatDestroy() 843 @*/ 844 PetscErrorCode MatSetUp(Mat A) 845 { 846 PetscMPIInt size; 847 PetscErrorCode ierr; 848 849 PetscFunctionBegin; 850 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 851 if (!((PetscObject)A)->type_name) { 852 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr); 853 if (size == 1) { 854 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr); 855 } else { 856 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr); 857 } 858 } 859 if (!A->preallocated && A->ops->setup) { 860 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 861 ierr = (*A->ops->setup)(A);CHKERRQ(ierr); 862 } 863 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 864 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 865 A->preallocated = PETSC_TRUE; 866 PetscFunctionReturn(0); 867 } 868 869 #if defined(PETSC_HAVE_SAWS) 870 #include <petscviewersaws.h> 871 #endif 872 /*@C 873 MatView - Visualizes a matrix object. 874 875 Collective on Mat 876 877 Input Parameters: 878 + mat - the matrix 879 - viewer - visualization context 880 881 Notes: 882 The available visualization contexts include 883 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 884 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 885 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 886 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 887 888 The user can open alternative visualization contexts with 889 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 890 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 891 specified file; corresponding input uses MatLoad() 892 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 893 an X window display 894 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 895 Currently only the sequential dense and AIJ 896 matrix types support the Socket viewer. 897 898 The user can call PetscViewerPushFormat() to specify the output 899 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 900 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 901 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 902 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 903 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 904 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 905 format common among all matrix types 906 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 907 format (which is in many cases the same as the default) 908 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 909 size and structure (not the matrix entries) 910 - PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 911 the matrix structure 912 913 Options Database Keys: 914 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 915 . -mat_view ::ascii_info_detail - Prints more detailed info 916 . -mat_view - Prints matrix in ASCII format 917 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 918 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 919 . -display <name> - Sets display name (default is host) 920 . -draw_pause <sec> - Sets number of seconds to pause after display 921 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 922 . -viewer_socket_machine <machine> - 923 . -viewer_socket_port <port> - 924 . -mat_view binary - save matrix to file in binary format 925 - -viewer_binary_filename <name> - 926 Level: beginner 927 928 Notes: 929 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 930 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 931 932 See the manual page for MatLoad() for the exact format of the binary file when the binary 933 viewer is used. 934 935 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 936 viewer is used. 937 938 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 939 and then use the following mouse functions. 940 + left mouse: zoom in 941 . middle mouse: zoom out 942 - right mouse: continue with the simulation 943 944 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 945 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 946 @*/ 947 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 948 { 949 PetscErrorCode ierr; 950 PetscInt rows,cols,rbs,cbs; 951 PetscBool iascii,ibinary,isstring; 952 PetscViewerFormat format; 953 PetscMPIInt size; 954 #if defined(PETSC_HAVE_SAWS) 955 PetscBool issaws; 956 #endif 957 958 PetscFunctionBegin; 959 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 960 PetscValidType(mat,1); 961 if (!viewer) { 962 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr); 963 } 964 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 965 PetscCheckSameComm(mat,1,viewer,2); 966 MatCheckPreallocated(mat,1); 967 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 968 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 969 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 970 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 971 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 972 if (ibinary) { 973 PetscBool mpiio; 974 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr); 975 if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag"); 976 } 977 978 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 979 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 980 if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 981 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed"); 982 } 983 984 #if defined(PETSC_HAVE_SAWS) 985 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 986 #endif 987 if (iascii) { 988 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 989 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr); 990 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 991 MatNullSpace nullsp,transnullsp; 992 993 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 994 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 995 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 996 if (rbs != 1 || cbs != 1) { 997 if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs=%D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);} 998 else {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);} 999 } else { 1000 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr); 1001 } 1002 if (mat->factortype) { 1003 MatSolverType solver; 1004 ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr); 1005 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr); 1006 } 1007 if (mat->ops->getinfo) { 1008 MatInfo info; 1009 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 1010 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr); 1011 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr); 1012 } 1013 ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr); 1014 ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr); 1015 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);} 1016 if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached transposed null space\n");CHKERRQ(ierr);} 1017 ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr); 1018 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached near null space\n");CHKERRQ(ierr);} 1019 } 1020 #if defined(PETSC_HAVE_SAWS) 1021 } else if (issaws) { 1022 PetscMPIInt rank; 1023 1024 ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr); 1025 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1026 if (!((PetscObject)mat)->amsmem && !rank) { 1027 ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr); 1028 } 1029 #endif 1030 } else if (isstring) { 1031 const char *type; 1032 ierr = MatGetType(mat,&type);CHKERRQ(ierr); 1033 ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr); 1034 if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);} 1035 } 1036 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1037 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1038 ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr); 1039 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1040 } else if (mat->ops->view) { 1041 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1042 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 1043 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1044 } 1045 if (iascii) { 1046 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1047 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1048 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1049 } 1050 } 1051 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1052 PetscFunctionReturn(0); 1053 } 1054 1055 #if defined(PETSC_USE_DEBUG) 1056 #include <../src/sys/totalview/tv_data_display.h> 1057 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1058 { 1059 TV_add_row("Local rows", "int", &mat->rmap->n); 1060 TV_add_row("Local columns", "int", &mat->cmap->n); 1061 TV_add_row("Global rows", "int", &mat->rmap->N); 1062 TV_add_row("Global columns", "int", &mat->cmap->N); 1063 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1064 return TV_format_OK; 1065 } 1066 #endif 1067 1068 /*@C 1069 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1070 with MatView(). The matrix format is determined from the options database. 1071 Generates a parallel MPI matrix if the communicator has more than one 1072 processor. The default matrix type is AIJ. 1073 1074 Collective on PetscViewer 1075 1076 Input Parameters: 1077 + newmat - the newly loaded matrix, this needs to have been created with MatCreate() 1078 or some related function before a call to MatLoad() 1079 - viewer - binary/HDF5 file viewer 1080 1081 Options Database Keys: 1082 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1083 block size 1084 . -matload_block_size <bs> 1085 1086 Level: beginner 1087 1088 Notes: 1089 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1090 Mat before calling this routine if you wish to set it from the options database. 1091 1092 MatLoad() automatically loads into the options database any options 1093 given in the file filename.info where filename is the name of the file 1094 that was passed to the PetscViewerBinaryOpen(). The options in the info 1095 file will be ignored if you use the -viewer_binary_skip_info option. 1096 1097 If the type or size of newmat is not set before a call to MatLoad, PETSc 1098 sets the default matrix type AIJ and sets the local and global sizes. 1099 If type and/or size is already set, then the same are used. 1100 1101 In parallel, each processor can load a subset of rows (or the 1102 entire matrix). This routine is especially useful when a large 1103 matrix is stored on disk and only part of it is desired on each 1104 processor. For example, a parallel solver may access only some of 1105 the rows from each processor. The algorithm used here reads 1106 relatively small blocks of data rather than reading the entire 1107 matrix and then subsetting it. 1108 1109 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5. 1110 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(), 1111 or the sequence like 1112 $ PetscViewer v; 1113 $ PetscViewerCreate(PETSC_COMM_WORLD,&v); 1114 $ PetscViewerSetType(v,PETSCVIEWERBINARY); 1115 $ PetscViewerSetFromOptions(v); 1116 $ PetscViewerFileSetMode(v,FILE_MODE_READ); 1117 $ PetscViewerFileSetName(v,"datafile"); 1118 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option 1119 $ -viewer_type {binary,hdf5} 1120 1121 See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach, 1122 and src/mat/examples/tutorials/ex10.c with the second approach. 1123 1124 Notes about the PETSc binary format: 1125 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks 1126 is read onto rank 0 and then shipped to its destination rank, one after another. 1127 Multiple objects, both matrices and vectors, can be stored within the same file. 1128 Their PetscObject name is ignored; they are loaded in the order of their storage. 1129 1130 Most users should not need to know the details of the binary storage 1131 format, since MatLoad() and MatView() completely hide these details. 1132 But for anyone who's interested, the standard binary matrix storage 1133 format is 1134 1135 $ PetscInt MAT_FILE_CLASSID 1136 $ PetscInt number of rows 1137 $ PetscInt number of columns 1138 $ PetscInt total number of nonzeros 1139 $ PetscInt *number nonzeros in each row 1140 $ PetscInt *column indices of all nonzeros (starting index is zero) 1141 $ PetscScalar *values of all nonzeros 1142 1143 PETSc automatically does the byte swapping for 1144 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1145 linux, Windows and the paragon; thus if you write your own binary 1146 read/write routines you have to swap the bytes; see PetscBinaryRead() 1147 and PetscBinaryWrite() to see how this may be done. 1148 1149 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1150 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used. 1151 Each processor's chunk is loaded independently by its owning rank. 1152 Multiple objects, both matrices and vectors, can be stored within the same file. 1153 They are looked up by their PetscObject name. 1154 1155 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1156 by default the same structure and naming of the AIJ arrays and column count 1157 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1158 $ save example.mat A b -v7.3 1159 can be directly read by this routine (see Reference 1 for details). 1160 Note that depending on your MATLAB version, this format might be a default, 1161 otherwise you can set it as default in Preferences. 1162 1163 Unless -nocompression flag is used to save the file in MATLAB, 1164 PETSc must be configured with ZLIB package. 1165 1166 See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c 1167 1168 Current HDF5 (MAT-File) limitations: 1169 This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices. 1170 1171 Corresponding MatView() is not yet implemented. 1172 1173 The loaded matrix is actually a transpose of the original one in MATLAB, 1174 unless you push PETSC_VIEWER_HDF5_MAT format (see examples above). 1175 With this format, matrix is automatically transposed by PETSc, 1176 unless the matrix is marked as SPD or symmetric 1177 (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC). 1178 1179 References: 1180 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1181 1182 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad() 1183 1184 @*/ 1185 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer) 1186 { 1187 PetscErrorCode ierr; 1188 PetscBool flg; 1189 1190 PetscFunctionBegin; 1191 PetscValidHeaderSpecific(newmat,MAT_CLASSID,1); 1192 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1193 1194 if (!((PetscObject)newmat)->type_name) { 1195 ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 1196 } 1197 1198 flg = PETSC_FALSE; 1199 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr); 1200 if (flg) { 1201 ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 1202 ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); 1203 } 1204 flg = PETSC_FALSE; 1205 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr); 1206 if (flg) { 1207 ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 1208 } 1209 1210 if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type"); 1211 ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1212 ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr); 1213 ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1214 PetscFunctionReturn(0); 1215 } 1216 1217 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1218 { 1219 PetscErrorCode ierr; 1220 Mat_Redundant *redund = *redundant; 1221 PetscInt i; 1222 1223 PetscFunctionBegin; 1224 if (redund){ 1225 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1226 ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr); 1227 ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr); 1228 ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr); 1229 } else { 1230 ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr); 1231 ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr); 1232 ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr); 1233 for (i=0; i<redund->nrecvs; i++) { 1234 ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr); 1235 ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr); 1236 } 1237 ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr); 1238 } 1239 1240 if (redund->subcomm) { 1241 ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr); 1242 } 1243 ierr = PetscFree(redund);CHKERRQ(ierr); 1244 } 1245 PetscFunctionReturn(0); 1246 } 1247 1248 /*@ 1249 MatDestroy - Frees space taken by a matrix. 1250 1251 Collective on Mat 1252 1253 Input Parameter: 1254 . A - the matrix 1255 1256 Level: beginner 1257 1258 @*/ 1259 PetscErrorCode MatDestroy(Mat *A) 1260 { 1261 PetscErrorCode ierr; 1262 1263 PetscFunctionBegin; 1264 if (!*A) PetscFunctionReturn(0); 1265 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1266 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1267 1268 /* if memory was published with SAWs then destroy it */ 1269 ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr); 1270 if ((*A)->ops->destroy) { 1271 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr); 1272 } 1273 1274 ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr); 1275 ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr); 1276 ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr); 1277 ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr); 1278 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr); 1279 ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr); 1280 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr); 1281 ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr); 1282 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr); 1283 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr); 1284 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr); 1285 PetscFunctionReturn(0); 1286 } 1287 1288 /*@C 1289 MatSetValues - Inserts or adds a block of values into a matrix. 1290 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1291 MUST be called after all calls to MatSetValues() have been completed. 1292 1293 Not Collective 1294 1295 Input Parameters: 1296 + mat - the matrix 1297 . v - a logically two-dimensional array of values 1298 . m, idxm - the number of rows and their global indices 1299 . n, idxn - the number of columns and their global indices 1300 - addv - either ADD_VALUES or INSERT_VALUES, where 1301 ADD_VALUES adds values to any existing entries, and 1302 INSERT_VALUES replaces existing entries with new values 1303 1304 Notes: 1305 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1306 MatSetUp() before using this routine 1307 1308 By default the values, v, are row-oriented. See MatSetOption() for other options. 1309 1310 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1311 options cannot be mixed without intervening calls to the assembly 1312 routines. 1313 1314 MatSetValues() uses 0-based row and column numbers in Fortran 1315 as well as in C. 1316 1317 Negative indices may be passed in idxm and idxn, these rows and columns are 1318 simply ignored. This allows easily inserting element stiffness matrices 1319 with homogeneous Dirchlet boundary conditions that you don't want represented 1320 in the matrix. 1321 1322 Efficiency Alert: 1323 The routine MatSetValuesBlocked() may offer much better efficiency 1324 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1325 1326 Level: beginner 1327 1328 Developer Notes: 1329 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1330 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1331 1332 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1333 InsertMode, INSERT_VALUES, ADD_VALUES 1334 @*/ 1335 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1336 { 1337 PetscErrorCode ierr; 1338 #if defined(PETSC_USE_DEBUG) 1339 PetscInt i,j; 1340 #endif 1341 1342 PetscFunctionBeginHot; 1343 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1344 PetscValidType(mat,1); 1345 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1346 PetscValidIntPointer(idxm,3); 1347 PetscValidIntPointer(idxn,5); 1348 MatCheckPreallocated(mat,1); 1349 1350 if (mat->insertmode == NOT_SET_VALUES) { 1351 mat->insertmode = addv; 1352 } 1353 #if defined(PETSC_USE_DEBUG) 1354 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1355 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1356 if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1357 1358 for (i=0; i<m; i++) { 1359 for (j=0; j<n; j++) { 1360 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1361 #if defined(PETSC_USE_COMPLEX) 1362 SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]); 1363 #else 1364 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]); 1365 #endif 1366 } 1367 } 1368 #endif 1369 1370 if (mat->assembled) { 1371 mat->was_assembled = PETSC_TRUE; 1372 mat->assembled = PETSC_FALSE; 1373 } 1374 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1375 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1376 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1377 PetscFunctionReturn(0); 1378 } 1379 1380 1381 /*@ 1382 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1383 values into a matrix 1384 1385 Not Collective 1386 1387 Input Parameters: 1388 + mat - the matrix 1389 . row - the (block) row to set 1390 - v - a logically two-dimensional array of values 1391 1392 Notes: 1393 By the values, v, are column-oriented (for the block version) and sorted 1394 1395 All the nonzeros in the row must be provided 1396 1397 The matrix must have previously had its column indices set 1398 1399 The row must belong to this process 1400 1401 Level: intermediate 1402 1403 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1404 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1405 @*/ 1406 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1407 { 1408 PetscErrorCode ierr; 1409 PetscInt globalrow; 1410 1411 PetscFunctionBegin; 1412 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1413 PetscValidType(mat,1); 1414 PetscValidScalarPointer(v,2); 1415 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr); 1416 ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr); 1417 PetscFunctionReturn(0); 1418 } 1419 1420 /*@ 1421 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1422 values into a matrix 1423 1424 Not Collective 1425 1426 Input Parameters: 1427 + mat - the matrix 1428 . row - the (block) row to set 1429 - 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 1430 1431 Notes: 1432 The values, v, are column-oriented for the block version. 1433 1434 All the nonzeros in the row must be provided 1435 1436 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1437 1438 The row must belong to this process 1439 1440 Level: advanced 1441 1442 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1443 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1444 @*/ 1445 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1446 { 1447 PetscErrorCode ierr; 1448 1449 PetscFunctionBeginHot; 1450 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1451 PetscValidType(mat,1); 1452 MatCheckPreallocated(mat,1); 1453 PetscValidScalarPointer(v,2); 1454 #if defined(PETSC_USE_DEBUG) 1455 if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1456 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1457 #endif 1458 mat->insertmode = INSERT_VALUES; 1459 1460 if (mat->assembled) { 1461 mat->was_assembled = PETSC_TRUE; 1462 mat->assembled = PETSC_FALSE; 1463 } 1464 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1465 if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1466 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr); 1467 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1468 PetscFunctionReturn(0); 1469 } 1470 1471 /*@ 1472 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1473 Using structured grid indexing 1474 1475 Not Collective 1476 1477 Input Parameters: 1478 + mat - the matrix 1479 . m - number of rows being entered 1480 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1481 . n - number of columns being entered 1482 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1483 . v - a logically two-dimensional array of values 1484 - addv - either ADD_VALUES or INSERT_VALUES, where 1485 ADD_VALUES adds values to any existing entries, and 1486 INSERT_VALUES replaces existing entries with new values 1487 1488 Notes: 1489 By default the values, v, are row-oriented. See MatSetOption() for other options. 1490 1491 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1492 options cannot be mixed without intervening calls to the assembly 1493 routines. 1494 1495 The grid coordinates are across the entire grid, not just the local portion 1496 1497 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1498 as well as in C. 1499 1500 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1501 1502 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1503 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1504 1505 The columns and rows in the stencil passed in MUST be contained within the 1506 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1507 if you create a DMDA with an overlap of one grid level and on a particular process its first 1508 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1509 first i index you can use in your column and row indices in MatSetStencil() is 5. 1510 1511 In Fortran idxm and idxn should be declared as 1512 $ MatStencil idxm(4,m),idxn(4,n) 1513 and the values inserted using 1514 $ idxm(MatStencil_i,1) = i 1515 $ idxm(MatStencil_j,1) = j 1516 $ idxm(MatStencil_k,1) = k 1517 $ idxm(MatStencil_c,1) = c 1518 etc 1519 1520 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1521 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1522 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1523 DM_BOUNDARY_PERIODIC boundary type. 1524 1525 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 1526 a single value per point) you can skip filling those indices. 1527 1528 Inspired by the structured grid interface to the HYPRE package 1529 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1530 1531 Efficiency Alert: 1532 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1533 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1534 1535 Level: beginner 1536 1537 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1538 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1539 @*/ 1540 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1541 { 1542 PetscErrorCode ierr; 1543 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1544 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1545 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1546 1547 PetscFunctionBegin; 1548 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1549 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1550 PetscValidType(mat,1); 1551 PetscValidIntPointer(idxm,3); 1552 PetscValidIntPointer(idxn,5); 1553 1554 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1555 jdxm = buf; jdxn = buf+m; 1556 } else { 1557 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1558 jdxm = bufm; jdxn = bufn; 1559 } 1560 for (i=0; i<m; i++) { 1561 for (j=0; j<3-sdim; j++) dxm++; 1562 tmp = *dxm++ - starts[0]; 1563 for (j=0; j<dim-1; j++) { 1564 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1565 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1566 } 1567 if (mat->stencil.noc) dxm++; 1568 jdxm[i] = tmp; 1569 } 1570 for (i=0; i<n; i++) { 1571 for (j=0; j<3-sdim; j++) dxn++; 1572 tmp = *dxn++ - starts[0]; 1573 for (j=0; j<dim-1; j++) { 1574 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1575 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1576 } 1577 if (mat->stencil.noc) dxn++; 1578 jdxn[i] = tmp; 1579 } 1580 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1581 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1582 PetscFunctionReturn(0); 1583 } 1584 1585 /*@ 1586 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1587 Using structured grid indexing 1588 1589 Not Collective 1590 1591 Input Parameters: 1592 + mat - the matrix 1593 . m - number of rows being entered 1594 . idxm - grid coordinates for matrix rows being entered 1595 . n - number of columns being entered 1596 . idxn - grid coordinates for matrix columns being entered 1597 . v - a logically two-dimensional array of values 1598 - addv - either ADD_VALUES or INSERT_VALUES, where 1599 ADD_VALUES adds values to any existing entries, and 1600 INSERT_VALUES replaces existing entries with new values 1601 1602 Notes: 1603 By default the values, v, are row-oriented and unsorted. 1604 See MatSetOption() for other options. 1605 1606 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1607 options cannot be mixed without intervening calls to the assembly 1608 routines. 1609 1610 The grid coordinates are across the entire grid, not just the local portion 1611 1612 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1613 as well as in C. 1614 1615 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1616 1617 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1618 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1619 1620 The columns and rows in the stencil passed in MUST be contained within the 1621 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1622 if you create a DMDA with an overlap of one grid level and on a particular process its first 1623 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1624 first i index you can use in your column and row indices in MatSetStencil() is 5. 1625 1626 In Fortran idxm and idxn should be declared as 1627 $ MatStencil idxm(4,m),idxn(4,n) 1628 and the values inserted using 1629 $ idxm(MatStencil_i,1) = i 1630 $ idxm(MatStencil_j,1) = j 1631 $ idxm(MatStencil_k,1) = k 1632 etc 1633 1634 Negative indices may be passed in idxm and idxn, these rows and columns are 1635 simply ignored. This allows easily inserting element stiffness matrices 1636 with homogeneous Dirchlet boundary conditions that you don't want represented 1637 in the matrix. 1638 1639 Inspired by the structured grid interface to the HYPRE package 1640 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1641 1642 Level: beginner 1643 1644 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1645 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1646 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1647 @*/ 1648 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1649 { 1650 PetscErrorCode ierr; 1651 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1652 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1653 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1654 1655 PetscFunctionBegin; 1656 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1657 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1658 PetscValidType(mat,1); 1659 PetscValidIntPointer(idxm,3); 1660 PetscValidIntPointer(idxn,5); 1661 PetscValidScalarPointer(v,6); 1662 1663 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1664 jdxm = buf; jdxn = buf+m; 1665 } else { 1666 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1667 jdxm = bufm; jdxn = bufn; 1668 } 1669 for (i=0; i<m; i++) { 1670 for (j=0; j<3-sdim; j++) dxm++; 1671 tmp = *dxm++ - starts[0]; 1672 for (j=0; j<sdim-1; j++) { 1673 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1674 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1675 } 1676 dxm++; 1677 jdxm[i] = tmp; 1678 } 1679 for (i=0; i<n; i++) { 1680 for (j=0; j<3-sdim; j++) dxn++; 1681 tmp = *dxn++ - starts[0]; 1682 for (j=0; j<sdim-1; j++) { 1683 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1684 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1685 } 1686 dxn++; 1687 jdxn[i] = tmp; 1688 } 1689 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1690 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1691 PetscFunctionReturn(0); 1692 } 1693 1694 /*@ 1695 MatSetStencil - Sets the grid information for setting values into a matrix via 1696 MatSetValuesStencil() 1697 1698 Not Collective 1699 1700 Input Parameters: 1701 + mat - the matrix 1702 . dim - dimension of the grid 1, 2, or 3 1703 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1704 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1705 - dof - number of degrees of freedom per node 1706 1707 1708 Inspired by the structured grid interface to the HYPRE package 1709 (www.llnl.gov/CASC/hyper) 1710 1711 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1712 user. 1713 1714 Level: beginner 1715 1716 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1717 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1718 @*/ 1719 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1720 { 1721 PetscInt i; 1722 1723 PetscFunctionBegin; 1724 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1725 PetscValidIntPointer(dims,3); 1726 PetscValidIntPointer(starts,4); 1727 1728 mat->stencil.dim = dim + (dof > 1); 1729 for (i=0; i<dim; i++) { 1730 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1731 mat->stencil.starts[i] = starts[dim-i-1]; 1732 } 1733 mat->stencil.dims[dim] = dof; 1734 mat->stencil.starts[dim] = 0; 1735 mat->stencil.noc = (PetscBool)(dof == 1); 1736 PetscFunctionReturn(0); 1737 } 1738 1739 /*@C 1740 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1741 1742 Not Collective 1743 1744 Input Parameters: 1745 + mat - the matrix 1746 . v - a logically two-dimensional array of values 1747 . m, idxm - the number of block rows and their global block indices 1748 . n, idxn - the number of block columns and their global block indices 1749 - addv - either ADD_VALUES or INSERT_VALUES, where 1750 ADD_VALUES adds values to any existing entries, and 1751 INSERT_VALUES replaces existing entries with new values 1752 1753 Notes: 1754 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1755 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1756 1757 The m and n count the NUMBER of blocks in the row direction and column direction, 1758 NOT the total number of rows/columns; for example, if the block size is 2 and 1759 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1760 The values in idxm would be 1 2; that is the first index for each block divided by 1761 the block size. 1762 1763 Note that you must call MatSetBlockSize() when constructing this matrix (before 1764 preallocating it). 1765 1766 By default the values, v, are row-oriented, so the layout of 1767 v is the same as for MatSetValues(). See MatSetOption() for other options. 1768 1769 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1770 options cannot be mixed without intervening calls to the assembly 1771 routines. 1772 1773 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1774 as well as in C. 1775 1776 Negative indices may be passed in idxm and idxn, these rows and columns are 1777 simply ignored. This allows easily inserting element stiffness matrices 1778 with homogeneous Dirchlet boundary conditions that you don't want represented 1779 in the matrix. 1780 1781 Each time an entry is set within a sparse matrix via MatSetValues(), 1782 internal searching must be done to determine where to place the 1783 data in the matrix storage space. By instead inserting blocks of 1784 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1785 reduced. 1786 1787 Example: 1788 $ Suppose m=n=2 and block size(bs) = 2 The array is 1789 $ 1790 $ 1 2 | 3 4 1791 $ 5 6 | 7 8 1792 $ - - - | - - - 1793 $ 9 10 | 11 12 1794 $ 13 14 | 15 16 1795 $ 1796 $ v[] should be passed in like 1797 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1798 $ 1799 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1800 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1801 1802 Level: intermediate 1803 1804 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1805 @*/ 1806 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1807 { 1808 PetscErrorCode ierr; 1809 1810 PetscFunctionBeginHot; 1811 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1812 PetscValidType(mat,1); 1813 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1814 PetscValidIntPointer(idxm,3); 1815 PetscValidIntPointer(idxn,5); 1816 PetscValidScalarPointer(v,6); 1817 MatCheckPreallocated(mat,1); 1818 if (mat->insertmode == NOT_SET_VALUES) { 1819 mat->insertmode = addv; 1820 } 1821 #if defined(PETSC_USE_DEBUG) 1822 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1823 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1824 if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1825 #endif 1826 1827 if (mat->assembled) { 1828 mat->was_assembled = PETSC_TRUE; 1829 mat->assembled = PETSC_FALSE; 1830 } 1831 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1832 if (mat->ops->setvaluesblocked) { 1833 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1834 } else { 1835 PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn; 1836 PetscInt i,j,bs,cbs; 1837 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr); 1838 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1839 iidxm = buf; iidxn = buf + m*bs; 1840 } else { 1841 ierr = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr); 1842 iidxm = bufr; iidxn = bufc; 1843 } 1844 for (i=0; i<m; i++) { 1845 for (j=0; j<bs; j++) { 1846 iidxm[i*bs+j] = bs*idxm[i] + j; 1847 } 1848 } 1849 for (i=0; i<n; i++) { 1850 for (j=0; j<cbs; j++) { 1851 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1852 } 1853 } 1854 ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr); 1855 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1856 } 1857 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1858 PetscFunctionReturn(0); 1859 } 1860 1861 /*@ 1862 MatGetValues - Gets a block of values from a matrix. 1863 1864 Not Collective; currently only returns a local block 1865 1866 Input Parameters: 1867 + mat - the matrix 1868 . v - a logically two-dimensional array for storing the values 1869 . m, idxm - the number of rows and their global indices 1870 - n, idxn - the number of columns and their global indices 1871 1872 Notes: 1873 The user must allocate space (m*n PetscScalars) for the values, v. 1874 The values, v, are then returned in a row-oriented format, 1875 analogous to that used by default in MatSetValues(). 1876 1877 MatGetValues() uses 0-based row and column numbers in 1878 Fortran as well as in C. 1879 1880 MatGetValues() requires that the matrix has been assembled 1881 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1882 MatSetValues() and MatGetValues() CANNOT be made in succession 1883 without intermediate matrix assembly. 1884 1885 Negative row or column indices will be ignored and those locations in v[] will be 1886 left unchanged. 1887 1888 Level: advanced 1889 1890 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues() 1891 @*/ 1892 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1893 { 1894 PetscErrorCode ierr; 1895 1896 PetscFunctionBegin; 1897 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1898 PetscValidType(mat,1); 1899 if (!m || !n) PetscFunctionReturn(0); 1900 PetscValidIntPointer(idxm,3); 1901 PetscValidIntPointer(idxn,5); 1902 PetscValidScalarPointer(v,6); 1903 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1904 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1905 if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1906 MatCheckPreallocated(mat,1); 1907 1908 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1909 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 1910 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1911 PetscFunctionReturn(0); 1912 } 1913 1914 /*@ 1915 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 1916 the same size. Currently, this can only be called once and creates the given matrix. 1917 1918 Not Collective 1919 1920 Input Parameters: 1921 + mat - the matrix 1922 . nb - the number of blocks 1923 . bs - the number of rows (and columns) in each block 1924 . rows - a concatenation of the rows for each block 1925 - v - a concatenation of logically two-dimensional arrays of values 1926 1927 Notes: 1928 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 1929 1930 Level: advanced 1931 1932 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1933 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1934 @*/ 1935 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 1936 { 1937 PetscErrorCode ierr; 1938 1939 PetscFunctionBegin; 1940 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1941 PetscValidType(mat,1); 1942 PetscValidScalarPointer(rows,4); 1943 PetscValidScalarPointer(v,5); 1944 #if defined(PETSC_USE_DEBUG) 1945 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1946 #endif 1947 1948 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1949 if (mat->ops->setvaluesbatch) { 1950 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr); 1951 } else { 1952 PetscInt b; 1953 for (b = 0; b < nb; ++b) { 1954 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr); 1955 } 1956 } 1957 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1958 PetscFunctionReturn(0); 1959 } 1960 1961 /*@ 1962 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 1963 the routine MatSetValuesLocal() to allow users to insert matrix entries 1964 using a local (per-processor) numbering. 1965 1966 Not Collective 1967 1968 Input Parameters: 1969 + x - the matrix 1970 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 1971 - cmapping - column mapping 1972 1973 Level: intermediate 1974 1975 1976 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal() 1977 @*/ 1978 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 1979 { 1980 PetscErrorCode ierr; 1981 1982 PetscFunctionBegin; 1983 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 1984 PetscValidType(x,1); 1985 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 1986 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 1987 1988 if (x->ops->setlocaltoglobalmapping) { 1989 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr); 1990 } else { 1991 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr); 1992 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr); 1993 } 1994 PetscFunctionReturn(0); 1995 } 1996 1997 1998 /*@ 1999 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2000 2001 Not Collective 2002 2003 Input Parameters: 2004 . A - the matrix 2005 2006 Output Parameters: 2007 + rmapping - row mapping 2008 - cmapping - column mapping 2009 2010 Level: advanced 2011 2012 2013 .seealso: MatSetValuesLocal() 2014 @*/ 2015 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2016 { 2017 PetscFunctionBegin; 2018 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2019 PetscValidType(A,1); 2020 if (rmapping) PetscValidPointer(rmapping,2); 2021 if (cmapping) PetscValidPointer(cmapping,3); 2022 if (rmapping) *rmapping = A->rmap->mapping; 2023 if (cmapping) *cmapping = A->cmap->mapping; 2024 PetscFunctionReturn(0); 2025 } 2026 2027 /*@ 2028 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2029 2030 Not Collective 2031 2032 Input Parameters: 2033 . A - the matrix 2034 2035 Output Parameters: 2036 + rmap - row layout 2037 - cmap - column layout 2038 2039 Level: advanced 2040 2041 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping() 2042 @*/ 2043 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2044 { 2045 PetscFunctionBegin; 2046 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2047 PetscValidType(A,1); 2048 if (rmap) PetscValidPointer(rmap,2); 2049 if (cmap) PetscValidPointer(cmap,3); 2050 if (rmap) *rmap = A->rmap; 2051 if (cmap) *cmap = A->cmap; 2052 PetscFunctionReturn(0); 2053 } 2054 2055 /*@C 2056 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2057 using a local ordering of the nodes. 2058 2059 Not Collective 2060 2061 Input Parameters: 2062 + mat - the matrix 2063 . nrow, irow - number of rows and their local indices 2064 . ncol, icol - number of columns and their local indices 2065 . y - a logically two-dimensional array of values 2066 - addv - either INSERT_VALUES or ADD_VALUES, where 2067 ADD_VALUES adds values to any existing entries, and 2068 INSERT_VALUES replaces existing entries with new values 2069 2070 Notes: 2071 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2072 MatSetUp() before using this routine 2073 2074 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2075 2076 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2077 options cannot be mixed without intervening calls to the assembly 2078 routines. 2079 2080 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2081 MUST be called after all calls to MatSetValuesLocal() have been completed. 2082 2083 Level: intermediate 2084 2085 Developer Notes: 2086 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2087 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2088 2089 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 2090 MatSetValueLocal() 2091 @*/ 2092 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2093 { 2094 PetscErrorCode ierr; 2095 2096 PetscFunctionBeginHot; 2097 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2098 PetscValidType(mat,1); 2099 MatCheckPreallocated(mat,1); 2100 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2101 PetscValidIntPointer(irow,3); 2102 PetscValidIntPointer(icol,5); 2103 if (mat->insertmode == NOT_SET_VALUES) { 2104 mat->insertmode = addv; 2105 } 2106 #if defined(PETSC_USE_DEBUG) 2107 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2108 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2109 if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2110 #endif 2111 2112 if (mat->assembled) { 2113 mat->was_assembled = PETSC_TRUE; 2114 mat->assembled = PETSC_FALSE; 2115 } 2116 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2117 if (mat->ops->setvalueslocal) { 2118 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2119 } else { 2120 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2121 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2122 irowm = buf; icolm = buf+nrow; 2123 } else { 2124 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2125 irowm = bufr; icolm = bufc; 2126 } 2127 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2128 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2129 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2130 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2131 } 2132 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2133 PetscFunctionReturn(0); 2134 } 2135 2136 /*@C 2137 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2138 using a local ordering of the nodes a block at a time. 2139 2140 Not Collective 2141 2142 Input Parameters: 2143 + x - the matrix 2144 . nrow, irow - number of rows and their local indices 2145 . ncol, icol - number of columns and their local indices 2146 . y - a logically two-dimensional array of values 2147 - addv - either INSERT_VALUES or ADD_VALUES, where 2148 ADD_VALUES adds values to any existing entries, and 2149 INSERT_VALUES replaces existing entries with new values 2150 2151 Notes: 2152 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2153 MatSetUp() before using this routine 2154 2155 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2156 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2157 2158 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2159 options cannot be mixed without intervening calls to the assembly 2160 routines. 2161 2162 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2163 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2164 2165 Level: intermediate 2166 2167 Developer Notes: 2168 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2169 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2170 2171 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(), 2172 MatSetValuesLocal(), MatSetValuesBlocked() 2173 @*/ 2174 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2175 { 2176 PetscErrorCode ierr; 2177 2178 PetscFunctionBeginHot; 2179 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2180 PetscValidType(mat,1); 2181 MatCheckPreallocated(mat,1); 2182 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2183 PetscValidIntPointer(irow,3); 2184 PetscValidIntPointer(icol,5); 2185 PetscValidScalarPointer(y,6); 2186 if (mat->insertmode == NOT_SET_VALUES) { 2187 mat->insertmode = addv; 2188 } 2189 #if defined(PETSC_USE_DEBUG) 2190 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2191 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2192 if (!mat->ops->setvaluesblockedlocal && !mat->ops->setvaluesblocked && !mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2193 #endif 2194 2195 if (mat->assembled) { 2196 mat->was_assembled = PETSC_TRUE; 2197 mat->assembled = PETSC_FALSE; 2198 } 2199 #if defined(PETSC_USE_DEBUG) 2200 /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2201 if (mat->rmap->mapping) { 2202 PetscInt irbs, rbs; 2203 ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr); 2204 ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr); 2205 if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs); 2206 } 2207 if (mat->cmap->mapping) { 2208 PetscInt icbs, cbs; 2209 ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr); 2210 ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr); 2211 if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs); 2212 } 2213 #endif 2214 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2215 if (mat->ops->setvaluesblockedlocal) { 2216 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2217 } else { 2218 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2219 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2220 irowm = buf; icolm = buf + nrow; 2221 } else { 2222 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2223 irowm = bufr; icolm = bufc; 2224 } 2225 ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2226 ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2227 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2228 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2229 } 2230 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2231 PetscFunctionReturn(0); 2232 } 2233 2234 /*@ 2235 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2236 2237 Collective on Mat 2238 2239 Input Parameters: 2240 + mat - the matrix 2241 - x - the vector to be multiplied 2242 2243 Output Parameters: 2244 . y - the result 2245 2246 Notes: 2247 The vectors x and y cannot be the same. I.e., one cannot 2248 call MatMult(A,y,y). 2249 2250 Level: developer 2251 2252 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2253 @*/ 2254 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2255 { 2256 PetscErrorCode ierr; 2257 2258 PetscFunctionBegin; 2259 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2260 PetscValidType(mat,1); 2261 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2262 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2263 2264 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2265 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2266 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2267 MatCheckPreallocated(mat,1); 2268 2269 if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2270 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr); 2271 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2272 PetscFunctionReturn(0); 2273 } 2274 2275 /* --------------------------------------------------------*/ 2276 /*@ 2277 MatMult - Computes the matrix-vector product, y = Ax. 2278 2279 Neighbor-wise Collective on Mat 2280 2281 Input Parameters: 2282 + mat - the matrix 2283 - x - the vector to be multiplied 2284 2285 Output Parameters: 2286 . y - the result 2287 2288 Notes: 2289 The vectors x and y cannot be the same. I.e., one cannot 2290 call MatMult(A,y,y). 2291 2292 Level: beginner 2293 2294 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2295 @*/ 2296 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2297 { 2298 PetscErrorCode ierr; 2299 2300 PetscFunctionBegin; 2301 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2302 PetscValidType(mat,1); 2303 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2304 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2305 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2306 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2307 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2308 #if !defined(PETSC_HAVE_CONSTRAINTS) 2309 if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 2310 if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N); 2311 if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n); 2312 #endif 2313 ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr); 2314 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2315 MatCheckPreallocated(mat,1); 2316 2317 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2318 if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2319 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2320 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2321 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2322 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2323 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2324 PetscFunctionReturn(0); 2325 } 2326 2327 /*@ 2328 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2329 2330 Neighbor-wise Collective on Mat 2331 2332 Input Parameters: 2333 + mat - the matrix 2334 - x - the vector to be multiplied 2335 2336 Output Parameters: 2337 . y - the result 2338 2339 Notes: 2340 The vectors x and y cannot be the same. I.e., one cannot 2341 call MatMultTranspose(A,y,y). 2342 2343 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2344 use MatMultHermitianTranspose() 2345 2346 Level: beginner 2347 2348 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2349 @*/ 2350 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2351 { 2352 PetscErrorCode ierr; 2353 2354 PetscFunctionBegin; 2355 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2356 PetscValidType(mat,1); 2357 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2358 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2359 2360 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2361 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2362 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2363 #if !defined(PETSC_HAVE_CONSTRAINTS) 2364 if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N); 2365 if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N); 2366 #endif 2367 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2368 MatCheckPreallocated(mat,1); 2369 2370 if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined"); 2371 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2372 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2373 ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr); 2374 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2375 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2376 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2377 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2378 PetscFunctionReturn(0); 2379 } 2380 2381 /*@ 2382 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2383 2384 Neighbor-wise Collective on Mat 2385 2386 Input Parameters: 2387 + mat - the matrix 2388 - x - the vector to be multilplied 2389 2390 Output Parameters: 2391 . y - the result 2392 2393 Notes: 2394 The vectors x and y cannot be the same. I.e., one cannot 2395 call MatMultHermitianTranspose(A,y,y). 2396 2397 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2398 2399 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2400 2401 Level: beginner 2402 2403 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2404 @*/ 2405 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2406 { 2407 PetscErrorCode ierr; 2408 Vec w; 2409 2410 PetscFunctionBegin; 2411 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2412 PetscValidType(mat,1); 2413 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2414 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2415 2416 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2417 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2418 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2419 #if !defined(PETSC_HAVE_CONSTRAINTS) 2420 if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N); 2421 if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N); 2422 #endif 2423 MatCheckPreallocated(mat,1); 2424 2425 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2426 if (mat->ops->multhermitiantranspose) { 2427 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2428 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr); 2429 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2430 } else { 2431 ierr = VecDuplicate(x,&w);CHKERRQ(ierr); 2432 ierr = VecCopy(x,w);CHKERRQ(ierr); 2433 ierr = VecConjugate(w);CHKERRQ(ierr); 2434 ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr); 2435 ierr = VecDestroy(&w);CHKERRQ(ierr); 2436 ierr = VecConjugate(y);CHKERRQ(ierr); 2437 } 2438 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2439 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2440 PetscFunctionReturn(0); 2441 } 2442 2443 /*@ 2444 MatMultAdd - Computes v3 = v2 + A * v1. 2445 2446 Neighbor-wise Collective on Mat 2447 2448 Input Parameters: 2449 + mat - the matrix 2450 - v1, v2 - the vectors 2451 2452 Output Parameters: 2453 . v3 - the result 2454 2455 Notes: 2456 The vectors v1 and v3 cannot be the same. I.e., one cannot 2457 call MatMultAdd(A,v1,v2,v1). 2458 2459 Level: beginner 2460 2461 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2462 @*/ 2463 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2464 { 2465 PetscErrorCode ierr; 2466 2467 PetscFunctionBegin; 2468 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2469 PetscValidType(mat,1); 2470 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2471 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2472 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2473 2474 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2475 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2476 if (mat->cmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->cmap->N,v1->map->N); 2477 /* if (mat->rmap->N != v2->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->rmap->N,v2->map->N); 2478 if (mat->rmap->N != v3->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->rmap->N,v3->map->N); */ 2479 if (mat->rmap->n != v3->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: local dim %D %D",mat->rmap->n,v3->map->n); 2480 if (mat->rmap->n != v2->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: local dim %D %D",mat->rmap->n,v2->map->n); 2481 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2482 MatCheckPreallocated(mat,1); 2483 2484 if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name); 2485 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2486 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2487 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2488 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2489 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2490 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2491 PetscFunctionReturn(0); 2492 } 2493 2494 /*@ 2495 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2496 2497 Neighbor-wise Collective on Mat 2498 2499 Input Parameters: 2500 + mat - the matrix 2501 - v1, v2 - the vectors 2502 2503 Output Parameters: 2504 . v3 - the result 2505 2506 Notes: 2507 The vectors v1 and v3 cannot be the same. I.e., one cannot 2508 call MatMultTransposeAdd(A,v1,v2,v1). 2509 2510 Level: beginner 2511 2512 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2513 @*/ 2514 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2515 { 2516 PetscErrorCode ierr; 2517 2518 PetscFunctionBegin; 2519 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2520 PetscValidType(mat,1); 2521 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2522 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2523 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2524 2525 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2526 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2527 if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2528 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2529 if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N); 2530 if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N); 2531 if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N); 2532 MatCheckPreallocated(mat,1); 2533 2534 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2535 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2536 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2537 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2538 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2539 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2540 PetscFunctionReturn(0); 2541 } 2542 2543 /*@ 2544 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2545 2546 Neighbor-wise Collective on Mat 2547 2548 Input Parameters: 2549 + mat - the matrix 2550 - v1, v2 - the vectors 2551 2552 Output Parameters: 2553 . v3 - the result 2554 2555 Notes: 2556 The vectors v1 and v3 cannot be the same. I.e., one cannot 2557 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2558 2559 Level: beginner 2560 2561 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2562 @*/ 2563 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2564 { 2565 PetscErrorCode ierr; 2566 2567 PetscFunctionBegin; 2568 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2569 PetscValidType(mat,1); 2570 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2571 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2572 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2573 2574 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2575 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2576 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2577 if (mat->rmap->N != v1->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v1: global dim %D %D",mat->rmap->N,v1->map->N); 2578 if (mat->cmap->N != v2->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v2: global dim %D %D",mat->cmap->N,v2->map->N); 2579 if (mat->cmap->N != v3->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec v3: global dim %D %D",mat->cmap->N,v3->map->N); 2580 MatCheckPreallocated(mat,1); 2581 2582 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2583 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2584 if (mat->ops->multhermitiantransposeadd) { 2585 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2586 } else { 2587 Vec w,z; 2588 ierr = VecDuplicate(v1,&w);CHKERRQ(ierr); 2589 ierr = VecCopy(v1,w);CHKERRQ(ierr); 2590 ierr = VecConjugate(w);CHKERRQ(ierr); 2591 ierr = VecDuplicate(v3,&z);CHKERRQ(ierr); 2592 ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr); 2593 ierr = VecDestroy(&w);CHKERRQ(ierr); 2594 ierr = VecConjugate(z);CHKERRQ(ierr); 2595 if (v2 != v3) { 2596 ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr); 2597 } else { 2598 ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr); 2599 } 2600 ierr = VecDestroy(&z);CHKERRQ(ierr); 2601 } 2602 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2603 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2604 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2605 PetscFunctionReturn(0); 2606 } 2607 2608 /*@ 2609 MatMultConstrained - The inner multiplication routine for a 2610 constrained matrix P^T A P. 2611 2612 Neighbor-wise Collective on Mat 2613 2614 Input Parameters: 2615 + mat - the matrix 2616 - x - the vector to be multilplied 2617 2618 Output Parameters: 2619 . y - the result 2620 2621 Notes: 2622 The vectors x and y cannot be the same. I.e., one cannot 2623 call MatMult(A,y,y). 2624 2625 Level: beginner 2626 2627 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2628 @*/ 2629 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y) 2630 { 2631 PetscErrorCode ierr; 2632 2633 PetscFunctionBegin; 2634 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2635 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2636 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2637 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2638 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2639 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2640 if (mat->cmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 2641 if (mat->rmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N); 2642 if (mat->rmap->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: local dim %D %D",mat->rmap->n,y->map->n); 2643 2644 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2645 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2646 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr); 2647 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2648 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2649 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2650 PetscFunctionReturn(0); 2651 } 2652 2653 /*@ 2654 MatMultTransposeConstrained - The inner multiplication routine for a 2655 constrained matrix P^T A^T P. 2656 2657 Neighbor-wise Collective on Mat 2658 2659 Input Parameters: 2660 + mat - the matrix 2661 - x - the vector to be multilplied 2662 2663 Output Parameters: 2664 . y - the result 2665 2666 Notes: 2667 The vectors x and y cannot be the same. I.e., one cannot 2668 call MatMult(A,y,y). 2669 2670 Level: beginner 2671 2672 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2673 @*/ 2674 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 2675 { 2676 PetscErrorCode ierr; 2677 2678 PetscFunctionBegin; 2679 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2680 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2681 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2682 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2683 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2684 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2685 if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 2686 if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N); 2687 2688 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2689 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 2690 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2691 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2692 PetscFunctionReturn(0); 2693 } 2694 2695 /*@C 2696 MatGetFactorType - gets the type of factorization it is 2697 2698 Not Collective 2699 2700 Input Parameters: 2701 . mat - the matrix 2702 2703 Output Parameters: 2704 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2705 2706 Level: intermediate 2707 2708 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType() 2709 @*/ 2710 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2711 { 2712 PetscFunctionBegin; 2713 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2714 PetscValidType(mat,1); 2715 PetscValidPointer(t,2); 2716 *t = mat->factortype; 2717 PetscFunctionReturn(0); 2718 } 2719 2720 /*@C 2721 MatSetFactorType - sets the type of factorization it is 2722 2723 Logically Collective on Mat 2724 2725 Input Parameters: 2726 + mat - the matrix 2727 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2728 2729 Level: intermediate 2730 2731 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType() 2732 @*/ 2733 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2734 { 2735 PetscFunctionBegin; 2736 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2737 PetscValidType(mat,1); 2738 mat->factortype = t; 2739 PetscFunctionReturn(0); 2740 } 2741 2742 /* ------------------------------------------------------------*/ 2743 /*@C 2744 MatGetInfo - Returns information about matrix storage (number of 2745 nonzeros, memory, etc.). 2746 2747 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2748 2749 Input Parameters: 2750 . mat - the matrix 2751 2752 Output Parameters: 2753 + flag - flag indicating the type of parameters to be returned 2754 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2755 MAT_GLOBAL_SUM - sum over all processors) 2756 - info - matrix information context 2757 2758 Notes: 2759 The MatInfo context contains a variety of matrix data, including 2760 number of nonzeros allocated and used, number of mallocs during 2761 matrix assembly, etc. Additional information for factored matrices 2762 is provided (such as the fill ratio, number of mallocs during 2763 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2764 when using the runtime options 2765 $ -info -mat_view ::ascii_info 2766 2767 Example for C/C++ Users: 2768 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2769 data within the MatInfo context. For example, 2770 .vb 2771 MatInfo info; 2772 Mat A; 2773 double mal, nz_a, nz_u; 2774 2775 MatGetInfo(A,MAT_LOCAL,&info); 2776 mal = info.mallocs; 2777 nz_a = info.nz_allocated; 2778 .ve 2779 2780 Example for Fortran Users: 2781 Fortran users should declare info as a double precision 2782 array of dimension MAT_INFO_SIZE, and then extract the parameters 2783 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2784 a complete list of parameter names. 2785 .vb 2786 double precision info(MAT_INFO_SIZE) 2787 double precision mal, nz_a 2788 Mat A 2789 integer ierr 2790 2791 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2792 mal = info(MAT_INFO_MALLOCS) 2793 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2794 .ve 2795 2796 Level: intermediate 2797 2798 Developer Note: fortran interface is not autogenerated as the f90 2799 interface defintion cannot be generated correctly [due to MatInfo] 2800 2801 .seealso: MatStashGetInfo() 2802 2803 @*/ 2804 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2805 { 2806 PetscErrorCode ierr; 2807 2808 PetscFunctionBegin; 2809 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2810 PetscValidType(mat,1); 2811 PetscValidPointer(info,3); 2812 if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2813 MatCheckPreallocated(mat,1); 2814 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 2815 PetscFunctionReturn(0); 2816 } 2817 2818 /* 2819 This is used by external packages where it is not easy to get the info from the actual 2820 matrix factorization. 2821 */ 2822 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2823 { 2824 PetscErrorCode ierr; 2825 2826 PetscFunctionBegin; 2827 ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr); 2828 PetscFunctionReturn(0); 2829 } 2830 2831 /* ----------------------------------------------------------*/ 2832 2833 /*@C 2834 MatLUFactor - Performs in-place LU factorization of matrix. 2835 2836 Collective on Mat 2837 2838 Input Parameters: 2839 + mat - the matrix 2840 . row - row permutation 2841 . col - column permutation 2842 - info - options for factorization, includes 2843 $ fill - expected fill as ratio of original fill. 2844 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2845 $ Run with the option -info to determine an optimal value to use 2846 2847 Notes: 2848 Most users should employ the simplified KSP interface for linear solvers 2849 instead of working directly with matrix algebra routines such as this. 2850 See, e.g., KSPCreate(). 2851 2852 This changes the state of the matrix to a factored matrix; it cannot be used 2853 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2854 2855 Level: developer 2856 2857 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 2858 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 2859 2860 Developer Note: fortran interface is not autogenerated as the f90 2861 interface defintion cannot be generated correctly [due to MatFactorInfo] 2862 2863 @*/ 2864 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2865 { 2866 PetscErrorCode ierr; 2867 MatFactorInfo tinfo; 2868 2869 PetscFunctionBegin; 2870 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2871 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2872 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2873 if (info) PetscValidPointer(info,4); 2874 PetscValidType(mat,1); 2875 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2876 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2877 if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2878 MatCheckPreallocated(mat,1); 2879 if (!info) { 2880 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2881 info = &tinfo; 2882 } 2883 2884 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2885 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 2886 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2887 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2888 PetscFunctionReturn(0); 2889 } 2890 2891 /*@C 2892 MatILUFactor - Performs in-place ILU factorization of matrix. 2893 2894 Collective on Mat 2895 2896 Input Parameters: 2897 + mat - the matrix 2898 . row - row permutation 2899 . col - column permutation 2900 - info - structure containing 2901 $ levels - number of levels of fill. 2902 $ expected fill - as ratio of original fill. 2903 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2904 missing diagonal entries) 2905 2906 Notes: 2907 Probably really in-place only when level of fill is zero, otherwise allocates 2908 new space to store factored matrix and deletes previous memory. 2909 2910 Most users should employ the simplified KSP interface for linear solvers 2911 instead of working directly with matrix algebra routines such as this. 2912 See, e.g., KSPCreate(). 2913 2914 Level: developer 2915 2916 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 2917 2918 Developer Note: fortran interface is not autogenerated as the f90 2919 interface defintion cannot be generated correctly [due to MatFactorInfo] 2920 2921 @*/ 2922 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2923 { 2924 PetscErrorCode ierr; 2925 2926 PetscFunctionBegin; 2927 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2928 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2929 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2930 PetscValidPointer(info,4); 2931 PetscValidType(mat,1); 2932 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 2933 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2934 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2935 if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2936 MatCheckPreallocated(mat,1); 2937 2938 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2939 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 2940 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2941 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2942 PetscFunctionReturn(0); 2943 } 2944 2945 /*@C 2946 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 2947 Call this routine before calling MatLUFactorNumeric(). 2948 2949 Collective on Mat 2950 2951 Input Parameters: 2952 + fact - the factor matrix obtained with MatGetFactor() 2953 . mat - the matrix 2954 . row, col - row and column permutations 2955 - info - options for factorization, includes 2956 $ fill - expected fill as ratio of original fill. 2957 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2958 $ Run with the option -info to determine an optimal value to use 2959 2960 2961 Notes: 2962 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 2963 2964 Most users should employ the simplified KSP interface for linear solvers 2965 instead of working directly with matrix algebra routines such as this. 2966 See, e.g., KSPCreate(). 2967 2968 Level: developer 2969 2970 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize() 2971 2972 Developer Note: fortran interface is not autogenerated as the f90 2973 interface defintion cannot be generated correctly [due to MatFactorInfo] 2974 2975 @*/ 2976 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 2977 { 2978 PetscErrorCode ierr; 2979 MatFactorInfo tinfo; 2980 2981 PetscFunctionBegin; 2982 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2983 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2984 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2985 if (info) PetscValidPointer(info,4); 2986 PetscValidType(mat,1); 2987 PetscValidPointer(fact,5); 2988 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2989 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2990 if (!(fact)->ops->lufactorsymbolic) { 2991 MatSolverType spackage; 2992 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 2993 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage); 2994 } 2995 MatCheckPreallocated(mat,2); 2996 if (!info) { 2997 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2998 info = &tinfo; 2999 } 3000 3001 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3002 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 3003 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3004 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3005 PetscFunctionReturn(0); 3006 } 3007 3008 /*@C 3009 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3010 Call this routine after first calling MatLUFactorSymbolic(). 3011 3012 Collective on Mat 3013 3014 Input Parameters: 3015 + fact - the factor matrix obtained with MatGetFactor() 3016 . mat - the matrix 3017 - info - options for factorization 3018 3019 Notes: 3020 See MatLUFactor() for in-place factorization. See 3021 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3022 3023 Most users should employ the simplified KSP interface for linear solvers 3024 instead of working directly with matrix algebra routines such as this. 3025 See, e.g., KSPCreate(). 3026 3027 Level: developer 3028 3029 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 3030 3031 Developer Note: fortran interface is not autogenerated as the f90 3032 interface defintion cannot be generated correctly [due to MatFactorInfo] 3033 3034 @*/ 3035 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3036 { 3037 MatFactorInfo tinfo; 3038 PetscErrorCode ierr; 3039 3040 PetscFunctionBegin; 3041 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3042 PetscValidType(mat,1); 3043 PetscValidPointer(fact,2); 3044 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3045 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3046 if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dimensions are different %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3047 3048 if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3049 MatCheckPreallocated(mat,2); 3050 if (!info) { 3051 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3052 info = &tinfo; 3053 } 3054 3055 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3056 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr); 3057 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3058 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3059 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3060 PetscFunctionReturn(0); 3061 } 3062 3063 /*@C 3064 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3065 symmetric matrix. 3066 3067 Collective on Mat 3068 3069 Input Parameters: 3070 + mat - the matrix 3071 . perm - row and column permutations 3072 - f - expected fill as ratio of original fill 3073 3074 Notes: 3075 See MatLUFactor() for the nonsymmetric case. See also 3076 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3077 3078 Most users should employ the simplified KSP interface for linear solvers 3079 instead of working directly with matrix algebra routines such as this. 3080 See, e.g., KSPCreate(). 3081 3082 Level: developer 3083 3084 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 3085 MatGetOrdering() 3086 3087 Developer Note: fortran interface is not autogenerated as the f90 3088 interface defintion cannot be generated correctly [due to MatFactorInfo] 3089 3090 @*/ 3091 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3092 { 3093 PetscErrorCode ierr; 3094 MatFactorInfo tinfo; 3095 3096 PetscFunctionBegin; 3097 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3098 PetscValidType(mat,1); 3099 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3100 if (info) PetscValidPointer(info,3); 3101 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3102 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3103 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3104 if (!mat->ops->choleskyfactor) SETERRQ1(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); 3105 MatCheckPreallocated(mat,1); 3106 if (!info) { 3107 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3108 info = &tinfo; 3109 } 3110 3111 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3112 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr); 3113 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3114 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3115 PetscFunctionReturn(0); 3116 } 3117 3118 /*@C 3119 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3120 of a symmetric matrix. 3121 3122 Collective on Mat 3123 3124 Input Parameters: 3125 + fact - the factor matrix obtained with MatGetFactor() 3126 . mat - the matrix 3127 . perm - row and column permutations 3128 - info - options for factorization, includes 3129 $ fill - expected fill as ratio of original fill. 3130 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3131 $ Run with the option -info to determine an optimal value to use 3132 3133 Notes: 3134 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3135 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3136 3137 Most users should employ the simplified KSP interface for linear solvers 3138 instead of working directly with matrix algebra routines such as this. 3139 See, e.g., KSPCreate(). 3140 3141 Level: developer 3142 3143 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 3144 MatGetOrdering() 3145 3146 Developer Note: fortran interface is not autogenerated as the f90 3147 interface defintion cannot be generated correctly [due to MatFactorInfo] 3148 3149 @*/ 3150 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3151 { 3152 PetscErrorCode ierr; 3153 MatFactorInfo tinfo; 3154 3155 PetscFunctionBegin; 3156 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3157 PetscValidType(mat,1); 3158 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3159 if (info) PetscValidPointer(info,3); 3160 PetscValidPointer(fact,4); 3161 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3162 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3163 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3164 if (!(fact)->ops->choleskyfactorsymbolic) { 3165 MatSolverType spackage; 3166 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3167 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage); 3168 } 3169 MatCheckPreallocated(mat,2); 3170 if (!info) { 3171 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3172 info = &tinfo; 3173 } 3174 3175 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3176 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 3177 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3178 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3179 PetscFunctionReturn(0); 3180 } 3181 3182 /*@C 3183 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3184 of a symmetric matrix. Call this routine after first calling 3185 MatCholeskyFactorSymbolic(). 3186 3187 Collective on Mat 3188 3189 Input Parameters: 3190 + fact - the factor matrix obtained with MatGetFactor() 3191 . mat - the initial matrix 3192 . info - options for factorization 3193 - fact - the symbolic factor of mat 3194 3195 3196 Notes: 3197 Most users should employ the simplified KSP interface for linear solvers 3198 instead of working directly with matrix algebra routines such as this. 3199 See, e.g., KSPCreate(). 3200 3201 Level: developer 3202 3203 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 3204 3205 Developer Note: fortran interface is not autogenerated as the f90 3206 interface defintion cannot be generated correctly [due to MatFactorInfo] 3207 3208 @*/ 3209 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3210 { 3211 MatFactorInfo tinfo; 3212 PetscErrorCode ierr; 3213 3214 PetscFunctionBegin; 3215 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3216 PetscValidType(mat,1); 3217 PetscValidPointer(fact,2); 3218 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3219 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3220 if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3221 if (mat->rmap->N != (fact)->rmap->N || mat->cmap->N != (fact)->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Mat fact: global dim %D should = %D %D should = %D",mat->rmap->N,(fact)->rmap->N,mat->cmap->N,(fact)->cmap->N); 3222 MatCheckPreallocated(mat,2); 3223 if (!info) { 3224 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3225 info = &tinfo; 3226 } 3227 3228 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3229 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr); 3230 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3231 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3232 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3233 PetscFunctionReturn(0); 3234 } 3235 3236 /* ----------------------------------------------------------------*/ 3237 /*@ 3238 MatSolve - Solves A x = b, given a factored matrix. 3239 3240 Neighbor-wise Collective on Mat 3241 3242 Input Parameters: 3243 + mat - the factored matrix 3244 - b - the right-hand-side vector 3245 3246 Output Parameter: 3247 . x - the result vector 3248 3249 Notes: 3250 The vectors b and x cannot be the same. I.e., one cannot 3251 call MatSolve(A,x,x). 3252 3253 Notes: 3254 Most users should employ the simplified KSP interface for linear solvers 3255 instead of working directly with matrix algebra routines such as this. 3256 See, e.g., KSPCreate(). 3257 3258 Level: developer 3259 3260 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3261 @*/ 3262 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3263 { 3264 PetscErrorCode ierr; 3265 3266 PetscFunctionBegin; 3267 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3268 PetscValidType(mat,1); 3269 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3270 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3271 PetscCheckSameComm(mat,1,b,2); 3272 PetscCheckSameComm(mat,1,x,3); 3273 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3274 if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 3275 if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N); 3276 if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n); 3277 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3278 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3279 MatCheckPreallocated(mat,1); 3280 3281 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3282 if (mat->factorerrortype) { 3283 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3284 ierr = VecSetInf(x);CHKERRQ(ierr); 3285 } else { 3286 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3287 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 3288 } 3289 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3290 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3291 PetscFunctionReturn(0); 3292 } 3293 3294 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans) 3295 { 3296 PetscErrorCode ierr; 3297 Vec b,x; 3298 PetscInt m,N,i; 3299 PetscScalar *bb,*xx; 3300 3301 PetscFunctionBegin; 3302 ierr = MatDenseGetArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr); 3303 ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr); 3304 ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr); /* number local rows */ 3305 ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr); /* total columns in dense matrix */ 3306 ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr); 3307 for (i=0; i<N; i++) { 3308 ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr); 3309 ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr); 3310 if (trans) { 3311 ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr); 3312 } else { 3313 ierr = MatSolve(A,b,x);CHKERRQ(ierr); 3314 } 3315 ierr = VecResetArray(x);CHKERRQ(ierr); 3316 ierr = VecResetArray(b);CHKERRQ(ierr); 3317 } 3318 ierr = VecDestroy(&b);CHKERRQ(ierr); 3319 ierr = VecDestroy(&x);CHKERRQ(ierr); 3320 ierr = MatDenseRestoreArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr); 3321 ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr); 3322 PetscFunctionReturn(0); 3323 } 3324 3325 /*@ 3326 MatMatSolve - Solves A X = B, given a factored matrix. 3327 3328 Neighbor-wise Collective on Mat 3329 3330 Input Parameters: 3331 + A - the factored matrix 3332 - B - the right-hand-side matrix (dense matrix) 3333 3334 Output Parameter: 3335 . X - the result matrix (dense matrix) 3336 3337 Notes: 3338 The matrices b and x cannot be the same. I.e., one cannot 3339 call MatMatSolve(A,x,x). 3340 3341 Notes: 3342 Most users should usually employ the simplified KSP interface for linear solvers 3343 instead of working directly with matrix algebra routines such as this. 3344 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3345 at a time. 3346 3347 When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS 3348 it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides. 3349 3350 Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B. 3351 3352 Level: developer 3353 3354 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3355 @*/ 3356 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3357 { 3358 PetscErrorCode ierr; 3359 3360 PetscFunctionBegin; 3361 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3362 PetscValidType(A,1); 3363 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3364 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3365 PetscCheckSameComm(A,1,B,2); 3366 PetscCheckSameComm(A,1,X,3); 3367 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3368 if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N); 3369 if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N); 3370 if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3371 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3372 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3373 MatCheckPreallocated(A,1); 3374 3375 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3376 if (!A->ops->matsolve) { 3377 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3378 ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr); 3379 } else { 3380 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr); 3381 } 3382 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3383 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3384 PetscFunctionReturn(0); 3385 } 3386 3387 /*@ 3388 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3389 3390 Neighbor-wise Collective on Mat 3391 3392 Input Parameters: 3393 + A - the factored matrix 3394 - B - the right-hand-side matrix (dense matrix) 3395 3396 Output Parameter: 3397 . X - the result matrix (dense matrix) 3398 3399 Notes: 3400 The matrices B and X cannot be the same. I.e., one cannot 3401 call MatMatSolveTranspose(A,X,X). 3402 3403 Notes: 3404 Most users should usually employ the simplified KSP interface for linear solvers 3405 instead of working directly with matrix algebra routines such as this. 3406 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3407 at a time. 3408 3409 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3410 3411 Level: developer 3412 3413 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor() 3414 @*/ 3415 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3416 { 3417 PetscErrorCode ierr; 3418 3419 PetscFunctionBegin; 3420 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3421 PetscValidType(A,1); 3422 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3423 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3424 PetscCheckSameComm(A,1,B,2); 3425 PetscCheckSameComm(A,1,X,3); 3426 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3427 if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N); 3428 if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N); 3429 if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n); 3430 if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3431 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3432 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3433 MatCheckPreallocated(A,1); 3434 3435 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3436 if (!A->ops->matsolvetranspose) { 3437 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3438 ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr); 3439 } else { 3440 ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr); 3441 } 3442 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3443 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3444 PetscFunctionReturn(0); 3445 } 3446 3447 /*@ 3448 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3449 3450 Neighbor-wise Collective on Mat 3451 3452 Input Parameters: 3453 + A - the factored matrix 3454 - Bt - the transpose of right-hand-side matrix 3455 3456 Output Parameter: 3457 . X - the result matrix (dense matrix) 3458 3459 Notes: 3460 Most users should usually employ the simplified KSP interface for linear solvers 3461 instead of working directly with matrix algebra routines such as this. 3462 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3463 at a time. 3464 3465 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(). 3466 3467 Level: developer 3468 3469 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3470 @*/ 3471 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3472 { 3473 PetscErrorCode ierr; 3474 3475 PetscFunctionBegin; 3476 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3477 PetscValidType(A,1); 3478 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3479 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3480 PetscCheckSameComm(A,1,Bt,2); 3481 PetscCheckSameComm(A,1,X,3); 3482 3483 if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3484 if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N); 3485 if (A->rmap->N != Bt->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %D %D",A->rmap->N,Bt->cmap->N); 3486 if (X->cmap->N < Bt->rmap->N) SETERRQ(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix"); 3487 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3488 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3489 MatCheckPreallocated(A,1); 3490 3491 if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3492 ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3493 ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr); 3494 ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3495 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3496 PetscFunctionReturn(0); 3497 } 3498 3499 /*@ 3500 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3501 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3502 3503 Neighbor-wise Collective on Mat 3504 3505 Input Parameters: 3506 + mat - the factored matrix 3507 - b - the right-hand-side vector 3508 3509 Output Parameter: 3510 . x - the result vector 3511 3512 Notes: 3513 MatSolve() should be used for most applications, as it performs 3514 a forward solve followed by a backward solve. 3515 3516 The vectors b and x cannot be the same, i.e., one cannot 3517 call MatForwardSolve(A,x,x). 3518 3519 For matrix in seqsbaij format with block size larger than 1, 3520 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3521 MatForwardSolve() solves U^T*D y = b, and 3522 MatBackwardSolve() solves U x = y. 3523 Thus they do not provide a symmetric preconditioner. 3524 3525 Most users should employ the simplified KSP interface for linear solvers 3526 instead of working directly with matrix algebra routines such as this. 3527 See, e.g., KSPCreate(). 3528 3529 Level: developer 3530 3531 .seealso: MatSolve(), MatBackwardSolve() 3532 @*/ 3533 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3534 { 3535 PetscErrorCode ierr; 3536 3537 PetscFunctionBegin; 3538 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3539 PetscValidType(mat,1); 3540 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3541 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3542 PetscCheckSameComm(mat,1,b,2); 3543 PetscCheckSameComm(mat,1,x,3); 3544 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3545 if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 3546 if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N); 3547 if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n); 3548 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3549 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3550 MatCheckPreallocated(mat,1); 3551 3552 if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3553 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3554 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 3555 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3556 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3557 PetscFunctionReturn(0); 3558 } 3559 3560 /*@ 3561 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3562 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3563 3564 Neighbor-wise Collective on Mat 3565 3566 Input Parameters: 3567 + mat - the factored matrix 3568 - b - the right-hand-side vector 3569 3570 Output Parameter: 3571 . x - the result vector 3572 3573 Notes: 3574 MatSolve() should be used for most applications, as it performs 3575 a forward solve followed by a backward solve. 3576 3577 The vectors b and x cannot be the same. I.e., one cannot 3578 call MatBackwardSolve(A,x,x). 3579 3580 For matrix in seqsbaij format with block size larger than 1, 3581 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3582 MatForwardSolve() solves U^T*D y = b, and 3583 MatBackwardSolve() solves U x = y. 3584 Thus they do not provide a symmetric preconditioner. 3585 3586 Most users should employ the simplified KSP interface for linear solvers 3587 instead of working directly with matrix algebra routines such as this. 3588 See, e.g., KSPCreate(). 3589 3590 Level: developer 3591 3592 .seealso: MatSolve(), MatForwardSolve() 3593 @*/ 3594 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3595 { 3596 PetscErrorCode ierr; 3597 3598 PetscFunctionBegin; 3599 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3600 PetscValidType(mat,1); 3601 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3602 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3603 PetscCheckSameComm(mat,1,b,2); 3604 PetscCheckSameComm(mat,1,x,3); 3605 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3606 if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 3607 if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N); 3608 if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n); 3609 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3610 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3611 MatCheckPreallocated(mat,1); 3612 3613 if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3614 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3615 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 3616 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3617 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3618 PetscFunctionReturn(0); 3619 } 3620 3621 /*@ 3622 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3623 3624 Neighbor-wise Collective on Mat 3625 3626 Input Parameters: 3627 + mat - the factored matrix 3628 . b - the right-hand-side vector 3629 - y - the vector to be added to 3630 3631 Output Parameter: 3632 . x - the result vector 3633 3634 Notes: 3635 The vectors b and x cannot be the same. I.e., one cannot 3636 call MatSolveAdd(A,x,y,x). 3637 3638 Most users should employ the simplified KSP interface for linear solvers 3639 instead of working directly with matrix algebra routines such as this. 3640 See, e.g., KSPCreate(). 3641 3642 Level: developer 3643 3644 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3645 @*/ 3646 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3647 { 3648 PetscScalar one = 1.0; 3649 Vec tmp; 3650 PetscErrorCode ierr; 3651 3652 PetscFunctionBegin; 3653 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3654 PetscValidType(mat,1); 3655 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3656 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3657 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3658 PetscCheckSameComm(mat,1,b,2); 3659 PetscCheckSameComm(mat,1,y,2); 3660 PetscCheckSameComm(mat,1,x,3); 3661 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3662 if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 3663 if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N); 3664 if (mat->rmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->rmap->N,y->map->N); 3665 if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n); 3666 if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n); 3667 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3668 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3669 MatCheckPreallocated(mat,1); 3670 3671 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3672 if (mat->ops->solveadd) { 3673 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 3674 } else { 3675 /* do the solve then the add manually */ 3676 if (x != y) { 3677 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3678 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3679 } else { 3680 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3681 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3682 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3683 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3684 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3685 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3686 } 3687 } 3688 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3689 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3690 PetscFunctionReturn(0); 3691 } 3692 3693 /*@ 3694 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3695 3696 Neighbor-wise Collective on Mat 3697 3698 Input Parameters: 3699 + mat - the factored matrix 3700 - b - the right-hand-side vector 3701 3702 Output Parameter: 3703 . x - the result vector 3704 3705 Notes: 3706 The vectors b and x cannot be the same. I.e., one cannot 3707 call MatSolveTranspose(A,x,x). 3708 3709 Most users should employ the simplified KSP interface for linear solvers 3710 instead of working directly with matrix algebra routines such as this. 3711 See, e.g., KSPCreate(). 3712 3713 Level: developer 3714 3715 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 3716 @*/ 3717 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3718 { 3719 PetscErrorCode ierr; 3720 3721 PetscFunctionBegin; 3722 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3723 PetscValidType(mat,1); 3724 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3725 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3726 PetscCheckSameComm(mat,1,b,2); 3727 PetscCheckSameComm(mat,1,x,3); 3728 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3729 if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N); 3730 if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N); 3731 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3732 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3733 MatCheckPreallocated(mat,1); 3734 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3735 if (mat->factorerrortype) { 3736 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3737 ierr = VecSetInf(x);CHKERRQ(ierr); 3738 } else { 3739 if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3740 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr); 3741 } 3742 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3743 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3744 PetscFunctionReturn(0); 3745 } 3746 3747 /*@ 3748 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3749 factored matrix. 3750 3751 Neighbor-wise Collective on Mat 3752 3753 Input Parameters: 3754 + mat - the factored matrix 3755 . b - the right-hand-side vector 3756 - y - the vector to be added to 3757 3758 Output Parameter: 3759 . x - the result vector 3760 3761 Notes: 3762 The vectors b and x cannot be the same. I.e., one cannot 3763 call MatSolveTransposeAdd(A,x,y,x). 3764 3765 Most users should employ the simplified KSP interface for linear solvers 3766 instead of working directly with matrix algebra routines such as this. 3767 See, e.g., KSPCreate(). 3768 3769 Level: developer 3770 3771 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 3772 @*/ 3773 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 3774 { 3775 PetscScalar one = 1.0; 3776 PetscErrorCode ierr; 3777 Vec tmp; 3778 3779 PetscFunctionBegin; 3780 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3781 PetscValidType(mat,1); 3782 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3783 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3784 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3785 PetscCheckSameComm(mat,1,b,2); 3786 PetscCheckSameComm(mat,1,y,3); 3787 PetscCheckSameComm(mat,1,x,4); 3788 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3789 if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N); 3790 if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N); 3791 if (mat->cmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N); 3792 if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n); 3793 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3794 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3795 MatCheckPreallocated(mat,1); 3796 3797 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3798 if (mat->ops->solvetransposeadd) { 3799 if (mat->factorerrortype) { 3800 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3801 ierr = VecSetInf(x);CHKERRQ(ierr); 3802 } else { 3803 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr); 3804 } 3805 } else { 3806 /* do the solve then the add manually */ 3807 if (x != y) { 3808 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3809 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3810 } else { 3811 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3812 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3813 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3814 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3815 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3816 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3817 } 3818 } 3819 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3820 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3821 PetscFunctionReturn(0); 3822 } 3823 /* ----------------------------------------------------------------*/ 3824 3825 /*@ 3826 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3827 3828 Neighbor-wise Collective on Mat 3829 3830 Input Parameters: 3831 + mat - the matrix 3832 . b - the right hand side 3833 . omega - the relaxation factor 3834 . flag - flag indicating the type of SOR (see below) 3835 . shift - diagonal shift 3836 . its - the number of iterations 3837 - lits - the number of local iterations 3838 3839 Output Parameters: 3840 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 3841 3842 SOR Flags: 3843 + SOR_FORWARD_SWEEP - forward SOR 3844 . SOR_BACKWARD_SWEEP - backward SOR 3845 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 3846 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 3847 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 3848 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 3849 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 3850 upper/lower triangular part of matrix to 3851 vector (with omega) 3852 - SOR_ZERO_INITIAL_GUESS - zero initial guess 3853 3854 Notes: 3855 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 3856 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 3857 on each processor. 3858 3859 Application programmers will not generally use MatSOR() directly, 3860 but instead will employ the KSP/PC interface. 3861 3862 Notes: 3863 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 3864 3865 Notes for Advanced Users: 3866 The flags are implemented as bitwise inclusive or operations. 3867 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 3868 to specify a zero initial guess for SSOR. 3869 3870 Most users should employ the simplified KSP interface for linear solvers 3871 instead of working directly with matrix algebra routines such as this. 3872 See, e.g., KSPCreate(). 3873 3874 Vectors x and b CANNOT be the same 3875 3876 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 3877 3878 Level: developer 3879 3880 @*/ 3881 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 3882 { 3883 PetscErrorCode ierr; 3884 3885 PetscFunctionBegin; 3886 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3887 PetscValidType(mat,1); 3888 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3889 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 3890 PetscCheckSameComm(mat,1,b,2); 3891 PetscCheckSameComm(mat,1,x,8); 3892 if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3893 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3894 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3895 if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 3896 if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N); 3897 if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n); 3898 if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its); 3899 if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits); 3900 if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 3901 3902 MatCheckPreallocated(mat,1); 3903 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3904 ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 3905 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3906 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3907 PetscFunctionReturn(0); 3908 } 3909 3910 /* 3911 Default matrix copy routine. 3912 */ 3913 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 3914 { 3915 PetscErrorCode ierr; 3916 PetscInt i,rstart = 0,rend = 0,nz; 3917 const PetscInt *cwork; 3918 const PetscScalar *vwork; 3919 3920 PetscFunctionBegin; 3921 if (B->assembled) { 3922 ierr = MatZeroEntries(B);CHKERRQ(ierr); 3923 } 3924 if (str == SAME_NONZERO_PATTERN) { 3925 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 3926 for (i=rstart; i<rend; i++) { 3927 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3928 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 3929 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3930 } 3931 } else { 3932 ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr); 3933 } 3934 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3935 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3936 PetscFunctionReturn(0); 3937 } 3938 3939 /*@ 3940 MatCopy - Copies a matrix to another matrix. 3941 3942 Collective on Mat 3943 3944 Input Parameters: 3945 + A - the matrix 3946 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 3947 3948 Output Parameter: 3949 . B - where the copy is put 3950 3951 Notes: 3952 If you use SAME_NONZERO_PATTERN then the two matrices had better have the 3953 same nonzero pattern or the routine will crash. 3954 3955 MatCopy() copies the matrix entries of a matrix to another existing 3956 matrix (after first zeroing the second matrix). A related routine is 3957 MatConvert(), which first creates a new matrix and then copies the data. 3958 3959 Level: intermediate 3960 3961 .seealso: MatConvert(), MatDuplicate() 3962 3963 @*/ 3964 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 3965 { 3966 PetscErrorCode ierr; 3967 PetscInt i; 3968 3969 PetscFunctionBegin; 3970 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3971 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3972 PetscValidType(A,1); 3973 PetscValidType(B,2); 3974 PetscCheckSameComm(A,1,B,2); 3975 MatCheckPreallocated(B,2); 3976 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3977 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3978 if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim (%D,%D) (%D,%D)",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N); 3979 MatCheckPreallocated(A,1); 3980 if (A == B) PetscFunctionReturn(0); 3981 3982 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 3983 if (A->ops->copy) { 3984 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 3985 } else { /* generic conversion */ 3986 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 3987 } 3988 3989 B->stencil.dim = A->stencil.dim; 3990 B->stencil.noc = A->stencil.noc; 3991 for (i=0; i<=A->stencil.dim; i++) { 3992 B->stencil.dims[i] = A->stencil.dims[i]; 3993 B->stencil.starts[i] = A->stencil.starts[i]; 3994 } 3995 3996 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 3997 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 3998 PetscFunctionReturn(0); 3999 } 4000 4001 /*@C 4002 MatConvert - Converts a matrix to another matrix, either of the same 4003 or different type. 4004 4005 Collective on Mat 4006 4007 Input Parameters: 4008 + mat - the matrix 4009 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4010 same type as the original matrix. 4011 - reuse - denotes if the destination matrix is to be created or reused. 4012 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 4013 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). 4014 4015 Output Parameter: 4016 . M - pointer to place new matrix 4017 4018 Notes: 4019 MatConvert() first creates a new matrix and then copies the data from 4020 the first matrix. A related routine is MatCopy(), which copies the matrix 4021 entries of one matrix to another already existing matrix context. 4022 4023 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4024 the MPI communicator of the generated matrix is always the same as the communicator 4025 of the input matrix. 4026 4027 Level: intermediate 4028 4029 .seealso: MatCopy(), MatDuplicate() 4030 @*/ 4031 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M) 4032 { 4033 PetscErrorCode ierr; 4034 PetscBool sametype,issame,flg; 4035 char convname[256],mtype[256]; 4036 Mat B; 4037 4038 PetscFunctionBegin; 4039 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4040 PetscValidType(mat,1); 4041 PetscValidPointer(M,3); 4042 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4043 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4044 MatCheckPreallocated(mat,1); 4045 4046 ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr); 4047 if (flg) newtype = mtype; 4048 4049 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 4050 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 4051 if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4052 if ((reuse == MAT_REUSE_MATRIX) && (mat == *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX"); 4053 4054 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4055 ierr = PetscInfo3(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr); 4056 PetscFunctionReturn(0); 4057 } 4058 4059 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4060 ierr = PetscInfo3(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr); 4061 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4062 } else { 4063 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4064 const char *prefix[3] = {"seq","mpi",""}; 4065 PetscInt i; 4066 /* 4067 Order of precedence: 4068 0) See if newtype is a superclass of the current matrix. 4069 1) See if a specialized converter is known to the current matrix. 4070 2) See if a specialized converter is known to the desired matrix class. 4071 3) See if a good general converter is registered for the desired class 4072 (as of 6/27/03 only MATMPIADJ falls into this category). 4073 4) See if a good general converter is known for the current matrix. 4074 5) Use a really basic converter. 4075 */ 4076 4077 /* 0) See if newtype is a superclass of the current matrix. 4078 i.e mat is mpiaij and newtype is aij */ 4079 for (i=0; i<2; i++) { 4080 ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4081 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4082 ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr); 4083 ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr); 4084 if (flg) { 4085 if (reuse == MAT_INPLACE_MATRIX) { 4086 PetscFunctionReturn(0); 4087 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4088 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4089 PetscFunctionReturn(0); 4090 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4091 ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4092 PetscFunctionReturn(0); 4093 } 4094 } 4095 } 4096 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4097 for (i=0; i<3; i++) { 4098 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4099 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4100 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4101 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4102 ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr); 4103 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4104 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr); 4105 ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4106 if (conv) goto foundconv; 4107 } 4108 4109 /* 2) See if a specialized converter is known to the desired matrix class. */ 4110 ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 4111 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr); 4112 ierr = MatSetType(B,newtype);CHKERRQ(ierr); 4113 for (i=0; i<3; i++) { 4114 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4115 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4116 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4117 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4118 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4119 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4120 ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 4121 ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4122 if (conv) { 4123 ierr = MatDestroy(&B);CHKERRQ(ierr); 4124 goto foundconv; 4125 } 4126 } 4127 4128 /* 3) See if a good general converter is registered for the desired class */ 4129 conv = B->ops->convertfrom; 4130 ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4131 ierr = MatDestroy(&B);CHKERRQ(ierr); 4132 if (conv) goto foundconv; 4133 4134 /* 4) See if a good general converter is known for the current matrix */ 4135 if (mat->ops->convert) { 4136 conv = mat->ops->convert; 4137 } 4138 ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4139 if (conv) goto foundconv; 4140 4141 /* 5) Use a really basic converter. */ 4142 ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr); 4143 conv = MatConvert_Basic; 4144 4145 foundconv: 4146 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4147 ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr); 4148 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4149 /* the block sizes must be same if the mappings are copied over */ 4150 (*M)->rmap->bs = mat->rmap->bs; 4151 (*M)->cmap->bs = mat->cmap->bs; 4152 ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr); 4153 ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr); 4154 (*M)->rmap->mapping = mat->rmap->mapping; 4155 (*M)->cmap->mapping = mat->cmap->mapping; 4156 } 4157 (*M)->stencil.dim = mat->stencil.dim; 4158 (*M)->stencil.noc = mat->stencil.noc; 4159 for (i=0; i<=mat->stencil.dim; i++) { 4160 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4161 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4162 } 4163 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4164 } 4165 ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr); 4166 4167 /* Copy Mat options */ 4168 if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);} 4169 if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);} 4170 PetscFunctionReturn(0); 4171 } 4172 4173 /*@C 4174 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4175 4176 Not Collective 4177 4178 Input Parameter: 4179 . mat - the matrix, must be a factored matrix 4180 4181 Output Parameter: 4182 . type - the string name of the package (do not free this string) 4183 4184 Notes: 4185 In Fortran you pass in a empty string and the package name will be copied into it. 4186 (Make sure the string is long enough) 4187 4188 Level: intermediate 4189 4190 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4191 @*/ 4192 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4193 { 4194 PetscErrorCode ierr, (*conv)(Mat,MatSolverType*); 4195 4196 PetscFunctionBegin; 4197 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4198 PetscValidType(mat,1); 4199 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4200 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr); 4201 if (!conv) { 4202 *type = MATSOLVERPETSC; 4203 } else { 4204 ierr = (*conv)(mat,type);CHKERRQ(ierr); 4205 } 4206 PetscFunctionReturn(0); 4207 } 4208 4209 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4210 struct _MatSolverTypeForSpecifcType { 4211 MatType mtype; 4212 PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*); 4213 MatSolverTypeForSpecifcType next; 4214 }; 4215 4216 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4217 struct _MatSolverTypeHolder { 4218 char *name; 4219 MatSolverTypeForSpecifcType handlers; 4220 MatSolverTypeHolder next; 4221 }; 4222 4223 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4224 4225 /*@C 4226 MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type 4227 4228 Input Parameters: 4229 + package - name of the package, for example petsc or superlu 4230 . mtype - the matrix type that works with this package 4231 . ftype - the type of factorization supported by the package 4232 - getfactor - routine that will create the factored matrix ready to be used 4233 4234 Level: intermediate 4235 4236 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4237 @*/ 4238 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*)) 4239 { 4240 PetscErrorCode ierr; 4241 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4242 PetscBool flg; 4243 MatSolverTypeForSpecifcType inext,iprev = NULL; 4244 4245 PetscFunctionBegin; 4246 ierr = MatInitializePackage();CHKERRQ(ierr); 4247 if (!next) { 4248 ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr); 4249 ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr); 4250 ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr); 4251 ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr); 4252 MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor; 4253 PetscFunctionReturn(0); 4254 } 4255 while (next) { 4256 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4257 if (flg) { 4258 if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4259 inext = next->handlers; 4260 while (inext) { 4261 ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4262 if (flg) { 4263 inext->getfactor[(int)ftype-1] = getfactor; 4264 PetscFunctionReturn(0); 4265 } 4266 iprev = inext; 4267 inext = inext->next; 4268 } 4269 ierr = PetscNew(&iprev->next);CHKERRQ(ierr); 4270 ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr); 4271 iprev->next->getfactor[(int)ftype-1] = getfactor; 4272 PetscFunctionReturn(0); 4273 } 4274 prev = next; 4275 next = next->next; 4276 } 4277 ierr = PetscNew(&prev->next);CHKERRQ(ierr); 4278 ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr); 4279 ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr); 4280 ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr); 4281 prev->next->handlers->getfactor[(int)ftype-1] = getfactor; 4282 PetscFunctionReturn(0); 4283 } 4284 4285 /*@C 4286 MatSolvePackageGet - Get's the function that creates the factor matrix if it exist 4287 4288 Input Parameters: 4289 + package - name of the package, for example petsc or superlu 4290 . ftype - the type of factorization supported by the package 4291 - mtype - the matrix type that works with this package 4292 4293 Output Parameters: 4294 + foundpackage - PETSC_TRUE if the package was registered 4295 . foundmtype - PETSC_TRUE if the package supports the requested mtype 4296 - getfactor - routine that will create the factored matrix ready to be used or NULL if not found 4297 4298 Level: intermediate 4299 4300 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4301 @*/ 4302 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*)) 4303 { 4304 PetscErrorCode ierr; 4305 MatSolverTypeHolder next = MatSolverTypeHolders; 4306 PetscBool flg; 4307 MatSolverTypeForSpecifcType inext; 4308 4309 PetscFunctionBegin; 4310 if (foundpackage) *foundpackage = PETSC_FALSE; 4311 if (foundmtype) *foundmtype = PETSC_FALSE; 4312 if (getfactor) *getfactor = NULL; 4313 4314 if (package) { 4315 while (next) { 4316 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4317 if (flg) { 4318 if (foundpackage) *foundpackage = PETSC_TRUE; 4319 inext = next->handlers; 4320 while (inext) { 4321 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4322 if (flg) { 4323 if (foundmtype) *foundmtype = PETSC_TRUE; 4324 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4325 PetscFunctionReturn(0); 4326 } 4327 inext = inext->next; 4328 } 4329 } 4330 next = next->next; 4331 } 4332 } else { 4333 while (next) { 4334 inext = next->handlers; 4335 while (inext) { 4336 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4337 if (flg && inext->getfactor[(int)ftype-1]) { 4338 if (foundpackage) *foundpackage = PETSC_TRUE; 4339 if (foundmtype) *foundmtype = PETSC_TRUE; 4340 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4341 PetscFunctionReturn(0); 4342 } 4343 inext = inext->next; 4344 } 4345 next = next->next; 4346 } 4347 } 4348 PetscFunctionReturn(0); 4349 } 4350 4351 PetscErrorCode MatSolverTypeDestroy(void) 4352 { 4353 PetscErrorCode ierr; 4354 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4355 MatSolverTypeForSpecifcType inext,iprev; 4356 4357 PetscFunctionBegin; 4358 while (next) { 4359 ierr = PetscFree(next->name);CHKERRQ(ierr); 4360 inext = next->handlers; 4361 while (inext) { 4362 ierr = PetscFree(inext->mtype);CHKERRQ(ierr); 4363 iprev = inext; 4364 inext = inext->next; 4365 ierr = PetscFree(iprev);CHKERRQ(ierr); 4366 } 4367 prev = next; 4368 next = next->next; 4369 ierr = PetscFree(prev);CHKERRQ(ierr); 4370 } 4371 MatSolverTypeHolders = NULL; 4372 PetscFunctionReturn(0); 4373 } 4374 4375 /*@C 4376 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4377 4378 Collective on Mat 4379 4380 Input Parameters: 4381 + mat - the matrix 4382 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4383 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4384 4385 Output Parameters: 4386 . f - the factor matrix used with MatXXFactorSymbolic() calls 4387 4388 Notes: 4389 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4390 such as pastix, superlu, mumps etc. 4391 4392 PETSc must have been ./configure to use the external solver, using the option --download-package 4393 4394 Level: intermediate 4395 4396 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4397 @*/ 4398 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4399 { 4400 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*); 4401 PetscBool foundpackage,foundmtype; 4402 4403 PetscFunctionBegin; 4404 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4405 PetscValidType(mat,1); 4406 4407 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4408 MatCheckPreallocated(mat,1); 4409 4410 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr); 4411 if (!foundpackage) { 4412 if (type) { 4413 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type); 4414 } else { 4415 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>"); 4416 } 4417 } 4418 4419 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4420 if (!conv) SETERRQ3(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); 4421 4422 #if defined(PETSC_USE_COMPLEX) 4423 if (mat->hermitian && !mat->symmetric && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported"); 4424 #endif 4425 4426 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4427 PetscFunctionReturn(0); 4428 } 4429 4430 /*@C 4431 MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type 4432 4433 Not Collective 4434 4435 Input Parameters: 4436 + mat - the matrix 4437 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4438 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4439 4440 Output Parameter: 4441 . flg - PETSC_TRUE if the factorization is available 4442 4443 Notes: 4444 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4445 such as pastix, superlu, mumps etc. 4446 4447 PETSc must have been ./configure to use the external solver, using the option --download-package 4448 4449 Level: intermediate 4450 4451 .seealso: MatCopy(), MatDuplicate(), MatGetFactor() 4452 @*/ 4453 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4454 { 4455 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4456 4457 PetscFunctionBegin; 4458 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4459 PetscValidType(mat,1); 4460 4461 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4462 MatCheckPreallocated(mat,1); 4463 4464 *flg = PETSC_FALSE; 4465 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4466 if (gconv) { 4467 *flg = PETSC_TRUE; 4468 } 4469 PetscFunctionReturn(0); 4470 } 4471 4472 #include <petscdmtypes.h> 4473 4474 /*@ 4475 MatDuplicate - Duplicates a matrix including the non-zero structure. 4476 4477 Collective on Mat 4478 4479 Input Parameters: 4480 + mat - the matrix 4481 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4482 See the manual page for MatDuplicateOption for an explanation of these options. 4483 4484 Output Parameter: 4485 . M - pointer to place new matrix 4486 4487 Level: intermediate 4488 4489 Notes: 4490 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4491 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. 4492 4493 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4494 @*/ 4495 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4496 { 4497 PetscErrorCode ierr; 4498 Mat B; 4499 PetscInt i; 4500 DM dm; 4501 void (*viewf)(void); 4502 4503 PetscFunctionBegin; 4504 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4505 PetscValidType(mat,1); 4506 PetscValidPointer(M,3); 4507 if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4508 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4509 MatCheckPreallocated(mat,1); 4510 4511 *M = 0; 4512 if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type"); 4513 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4514 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4515 B = *M; 4516 4517 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr); 4518 if (viewf) { 4519 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr); 4520 } 4521 4522 B->stencil.dim = mat->stencil.dim; 4523 B->stencil.noc = mat->stencil.noc; 4524 for (i=0; i<=mat->stencil.dim; i++) { 4525 B->stencil.dims[i] = mat->stencil.dims[i]; 4526 B->stencil.starts[i] = mat->stencil.starts[i]; 4527 } 4528 4529 B->nooffproczerorows = mat->nooffproczerorows; 4530 B->nooffprocentries = mat->nooffprocentries; 4531 4532 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr); 4533 if (dm) { 4534 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 4535 } 4536 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4537 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4538 PetscFunctionReturn(0); 4539 } 4540 4541 /*@ 4542 MatGetDiagonal - Gets the diagonal of a matrix. 4543 4544 Logically Collective on Mat 4545 4546 Input Parameters: 4547 + mat - the matrix 4548 - v - the vector for storing the diagonal 4549 4550 Output Parameter: 4551 . v - the diagonal of the matrix 4552 4553 Level: intermediate 4554 4555 Note: 4556 Currently only correct in parallel for square matrices. 4557 4558 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4559 @*/ 4560 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4561 { 4562 PetscErrorCode ierr; 4563 4564 PetscFunctionBegin; 4565 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4566 PetscValidType(mat,1); 4567 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4568 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4569 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4570 MatCheckPreallocated(mat,1); 4571 4572 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4573 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4574 PetscFunctionReturn(0); 4575 } 4576 4577 /*@C 4578 MatGetRowMin - Gets the minimum value (of the real part) of each 4579 row of the matrix 4580 4581 Logically Collective on Mat 4582 4583 Input Parameters: 4584 . mat - the matrix 4585 4586 Output Parameter: 4587 + v - the vector for storing the maximums 4588 - idx - the indices of the column found for each row (optional) 4589 4590 Level: intermediate 4591 4592 Notes: 4593 The result of this call are the same as if one converted the matrix to dense format 4594 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4595 4596 This code is only implemented for a couple of matrix formats. 4597 4598 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4599 MatGetRowMax() 4600 @*/ 4601 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4602 { 4603 PetscErrorCode ierr; 4604 4605 PetscFunctionBegin; 4606 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4607 PetscValidType(mat,1); 4608 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4609 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4610 if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4611 MatCheckPreallocated(mat,1); 4612 4613 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4614 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4615 PetscFunctionReturn(0); 4616 } 4617 4618 /*@C 4619 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4620 row of the matrix 4621 4622 Logically Collective on Mat 4623 4624 Input Parameters: 4625 . mat - the matrix 4626 4627 Output Parameter: 4628 + v - the vector for storing the minimums 4629 - idx - the indices of the column found for each row (or NULL if not needed) 4630 4631 Level: intermediate 4632 4633 Notes: 4634 if a row is completely empty or has only 0.0 values then the idx[] value for that 4635 row is 0 (the first column). 4636 4637 This code is only implemented for a couple of matrix formats. 4638 4639 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4640 @*/ 4641 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4642 { 4643 PetscErrorCode ierr; 4644 4645 PetscFunctionBegin; 4646 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4647 PetscValidType(mat,1); 4648 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4649 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4650 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4651 MatCheckPreallocated(mat,1); 4652 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 4653 4654 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4655 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4656 PetscFunctionReturn(0); 4657 } 4658 4659 /*@C 4660 MatGetRowMax - Gets the maximum value (of the real part) of each 4661 row of the matrix 4662 4663 Logically Collective on Mat 4664 4665 Input Parameters: 4666 . mat - the matrix 4667 4668 Output Parameter: 4669 + v - the vector for storing the maximums 4670 - idx - the indices of the column found for each row (optional) 4671 4672 Level: intermediate 4673 4674 Notes: 4675 The result of this call are the same as if one converted the matrix to dense format 4676 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4677 4678 This code is only implemented for a couple of matrix formats. 4679 4680 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4681 @*/ 4682 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4683 { 4684 PetscErrorCode ierr; 4685 4686 PetscFunctionBegin; 4687 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4688 PetscValidType(mat,1); 4689 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4690 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4691 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4692 MatCheckPreallocated(mat,1); 4693 4694 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4695 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4696 PetscFunctionReturn(0); 4697 } 4698 4699 /*@C 4700 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4701 row of the matrix 4702 4703 Logically Collective on Mat 4704 4705 Input Parameters: 4706 . mat - the matrix 4707 4708 Output Parameter: 4709 + v - the vector for storing the maximums 4710 - idx - the indices of the column found for each row (or NULL if not needed) 4711 4712 Level: intermediate 4713 4714 Notes: 4715 if a row is completely empty or has only 0.0 values then the idx[] value for that 4716 row is 0 (the first column). 4717 4718 This code is only implemented for a couple of matrix formats. 4719 4720 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4721 @*/ 4722 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4723 { 4724 PetscErrorCode ierr; 4725 4726 PetscFunctionBegin; 4727 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4728 PetscValidType(mat,1); 4729 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4730 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4731 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4732 MatCheckPreallocated(mat,1); 4733 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 4734 4735 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4736 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4737 PetscFunctionReturn(0); 4738 } 4739 4740 /*@ 4741 MatGetRowSum - Gets the sum of each row of the matrix 4742 4743 Logically or Neighborhood Collective on Mat 4744 4745 Input Parameters: 4746 . mat - the matrix 4747 4748 Output Parameter: 4749 . v - the vector for storing the sum of rows 4750 4751 Level: intermediate 4752 4753 Notes: 4754 This code is slow since it is not currently specialized for different formats 4755 4756 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4757 @*/ 4758 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4759 { 4760 Vec ones; 4761 PetscErrorCode ierr; 4762 4763 PetscFunctionBegin; 4764 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4765 PetscValidType(mat,1); 4766 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4767 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4768 MatCheckPreallocated(mat,1); 4769 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr); 4770 ierr = VecSet(ones,1.);CHKERRQ(ierr); 4771 ierr = MatMult(mat,ones,v);CHKERRQ(ierr); 4772 ierr = VecDestroy(&ones);CHKERRQ(ierr); 4773 PetscFunctionReturn(0); 4774 } 4775 4776 /*@ 4777 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4778 4779 Collective on Mat 4780 4781 Input Parameter: 4782 + mat - the matrix to transpose 4783 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 4784 4785 Output Parameters: 4786 . B - the transpose 4787 4788 Notes: 4789 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 4790 4791 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 4792 4793 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4794 4795 Level: intermediate 4796 4797 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4798 @*/ 4799 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4800 { 4801 PetscErrorCode ierr; 4802 4803 PetscFunctionBegin; 4804 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4805 PetscValidType(mat,1); 4806 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4807 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4808 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4809 if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 4810 if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 4811 MatCheckPreallocated(mat,1); 4812 4813 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4814 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 4815 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4816 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 4817 PetscFunctionReturn(0); 4818 } 4819 4820 /*@ 4821 MatIsTranspose - Test whether a matrix is another one's transpose, 4822 or its own, in which case it tests symmetry. 4823 4824 Collective on Mat 4825 4826 Input Parameter: 4827 + A - the matrix to test 4828 - B - the matrix to test against, this can equal the first parameter 4829 4830 Output Parameters: 4831 . flg - the result 4832 4833 Notes: 4834 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4835 has a running time of the order of the number of nonzeros; the parallel 4836 test involves parallel copies of the block-offdiagonal parts of the matrix. 4837 4838 Level: intermediate 4839 4840 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 4841 @*/ 4842 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4843 { 4844 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4845 4846 PetscFunctionBegin; 4847 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4848 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4849 PetscValidBoolPointer(flg,3); 4850 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 4851 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 4852 *flg = PETSC_FALSE; 4853 if (f && g) { 4854 if (f == g) { 4855 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4856 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 4857 } else { 4858 MatType mattype; 4859 if (!f) { 4860 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 4861 } else { 4862 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 4863 } 4864 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype); 4865 } 4866 PetscFunctionReturn(0); 4867 } 4868 4869 /*@ 4870 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 4871 4872 Collective on Mat 4873 4874 Input Parameter: 4875 + mat - the matrix to transpose and complex conjugate 4876 - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose 4877 4878 Output Parameters: 4879 . B - the Hermitian 4880 4881 Level: intermediate 4882 4883 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4884 @*/ 4885 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 4886 { 4887 PetscErrorCode ierr; 4888 4889 PetscFunctionBegin; 4890 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 4891 #if defined(PETSC_USE_COMPLEX) 4892 ierr = MatConjugate(*B);CHKERRQ(ierr); 4893 #endif 4894 PetscFunctionReturn(0); 4895 } 4896 4897 /*@ 4898 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 4899 4900 Collective on Mat 4901 4902 Input Parameter: 4903 + A - the matrix to test 4904 - B - the matrix to test against, this can equal the first parameter 4905 4906 Output Parameters: 4907 . flg - the result 4908 4909 Notes: 4910 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4911 has a running time of the order of the number of nonzeros; the parallel 4912 test involves parallel copies of the block-offdiagonal parts of the matrix. 4913 4914 Level: intermediate 4915 4916 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 4917 @*/ 4918 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4919 { 4920 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4921 4922 PetscFunctionBegin; 4923 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4924 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4925 PetscValidBoolPointer(flg,3); 4926 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 4927 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 4928 if (f && g) { 4929 if (f==g) { 4930 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4931 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 4932 } 4933 PetscFunctionReturn(0); 4934 } 4935 4936 /*@ 4937 MatPermute - Creates a new matrix with rows and columns permuted from the 4938 original. 4939 4940 Collective on Mat 4941 4942 Input Parameters: 4943 + mat - the matrix to permute 4944 . row - row permutation, each processor supplies only the permutation for its rows 4945 - col - column permutation, each processor supplies only the permutation for its columns 4946 4947 Output Parameters: 4948 . B - the permuted matrix 4949 4950 Level: advanced 4951 4952 Note: 4953 The index sets map from row/col of permuted matrix to row/col of original matrix. 4954 The index sets should be on the same communicator as Mat and have the same local sizes. 4955 4956 .seealso: MatGetOrdering(), ISAllGather() 4957 4958 @*/ 4959 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 4960 { 4961 PetscErrorCode ierr; 4962 4963 PetscFunctionBegin; 4964 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4965 PetscValidType(mat,1); 4966 PetscValidHeaderSpecific(row,IS_CLASSID,2); 4967 PetscValidHeaderSpecific(col,IS_CLASSID,3); 4968 PetscValidPointer(B,4); 4969 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4970 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4971 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 4972 MatCheckPreallocated(mat,1); 4973 4974 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 4975 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 4976 PetscFunctionReturn(0); 4977 } 4978 4979 /*@ 4980 MatEqual - Compares two matrices. 4981 4982 Collective on Mat 4983 4984 Input Parameters: 4985 + A - the first matrix 4986 - B - the second matrix 4987 4988 Output Parameter: 4989 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 4990 4991 Level: intermediate 4992 4993 @*/ 4994 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 4995 { 4996 PetscErrorCode ierr; 4997 4998 PetscFunctionBegin; 4999 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5000 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5001 PetscValidType(A,1); 5002 PetscValidType(B,2); 5003 PetscValidBoolPointer(flg,3); 5004 PetscCheckSameComm(A,1,B,2); 5005 MatCheckPreallocated(B,2); 5006 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5007 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5008 if (A->rmap->N != B->rmap->N || A->cmap->N != B->cmap->N) SETERRQ4(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D %D %D",A->rmap->N,B->rmap->N,A->cmap->N,B->cmap->N); 5009 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5010 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 5011 if (A->ops->equal != B->ops->equal) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"A is type: %s\nB is type: %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 5012 MatCheckPreallocated(A,1); 5013 5014 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 5015 PetscFunctionReturn(0); 5016 } 5017 5018 /*@ 5019 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5020 matrices that are stored as vectors. Either of the two scaling 5021 matrices can be NULL. 5022 5023 Collective on Mat 5024 5025 Input Parameters: 5026 + mat - the matrix to be scaled 5027 . l - the left scaling vector (or NULL) 5028 - r - the right scaling vector (or NULL) 5029 5030 Notes: 5031 MatDiagonalScale() computes A = LAR, where 5032 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5033 The L scales the rows of the matrix, the R scales the columns of the matrix. 5034 5035 Level: intermediate 5036 5037 5038 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5039 @*/ 5040 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5041 { 5042 PetscErrorCode ierr; 5043 5044 PetscFunctionBegin; 5045 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5046 PetscValidType(mat,1); 5047 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5048 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5049 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5050 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5051 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5052 MatCheckPreallocated(mat,1); 5053 5054 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5055 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 5056 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5057 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5058 PetscFunctionReturn(0); 5059 } 5060 5061 /*@ 5062 MatScale - Scales all elements of a matrix by a given number. 5063 5064 Logically Collective on Mat 5065 5066 Input Parameters: 5067 + mat - the matrix to be scaled 5068 - a - the scaling value 5069 5070 Output Parameter: 5071 . mat - the scaled matrix 5072 5073 Level: intermediate 5074 5075 .seealso: MatDiagonalScale() 5076 @*/ 5077 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5078 { 5079 PetscErrorCode ierr; 5080 5081 PetscFunctionBegin; 5082 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5083 PetscValidType(mat,1); 5084 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5085 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5086 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5087 PetscValidLogicalCollectiveScalar(mat,a,2); 5088 MatCheckPreallocated(mat,1); 5089 5090 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5091 if (a != (PetscScalar)1.0) { 5092 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5093 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5094 } 5095 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5096 PetscFunctionReturn(0); 5097 } 5098 5099 /*@ 5100 MatNorm - Calculates various norms of a matrix. 5101 5102 Collective on Mat 5103 5104 Input Parameters: 5105 + mat - the matrix 5106 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5107 5108 Output Parameters: 5109 . nrm - the resulting norm 5110 5111 Level: intermediate 5112 5113 @*/ 5114 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5115 { 5116 PetscErrorCode ierr; 5117 5118 PetscFunctionBegin; 5119 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5120 PetscValidType(mat,1); 5121 PetscValidScalarPointer(nrm,3); 5122 5123 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5124 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5125 if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5126 MatCheckPreallocated(mat,1); 5127 5128 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5129 PetscFunctionReturn(0); 5130 } 5131 5132 /* 5133 This variable is used to prevent counting of MatAssemblyBegin() that 5134 are called from within a MatAssemblyEnd(). 5135 */ 5136 static PetscInt MatAssemblyEnd_InUse = 0; 5137 /*@ 5138 MatAssemblyBegin - Begins assembling the matrix. This routine should 5139 be called after completing all calls to MatSetValues(). 5140 5141 Collective on Mat 5142 5143 Input Parameters: 5144 + mat - the matrix 5145 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5146 5147 Notes: 5148 MatSetValues() generally caches the values. The matrix is ready to 5149 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5150 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5151 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5152 using the matrix. 5153 5154 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5155 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 5156 a global collective operation requring all processes that share the matrix. 5157 5158 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5159 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5160 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5161 5162 Level: beginner 5163 5164 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5165 @*/ 5166 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5167 { 5168 PetscErrorCode ierr; 5169 5170 PetscFunctionBegin; 5171 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5172 PetscValidType(mat,1); 5173 MatCheckPreallocated(mat,1); 5174 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5175 if (mat->assembled) { 5176 mat->was_assembled = PETSC_TRUE; 5177 mat->assembled = PETSC_FALSE; 5178 } 5179 5180 if (!MatAssemblyEnd_InUse) { 5181 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5182 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5183 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5184 } else if (mat->ops->assemblybegin) { 5185 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5186 } 5187 PetscFunctionReturn(0); 5188 } 5189 5190 /*@ 5191 MatAssembled - Indicates if a matrix has been assembled and is ready for 5192 use; for example, in matrix-vector product. 5193 5194 Not Collective 5195 5196 Input Parameter: 5197 . mat - the matrix 5198 5199 Output Parameter: 5200 . assembled - PETSC_TRUE or PETSC_FALSE 5201 5202 Level: advanced 5203 5204 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5205 @*/ 5206 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5207 { 5208 PetscFunctionBegin; 5209 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5210 PetscValidPointer(assembled,2); 5211 *assembled = mat->assembled; 5212 PetscFunctionReturn(0); 5213 } 5214 5215 /*@ 5216 MatAssemblyEnd - Completes assembling the matrix. This routine should 5217 be called after MatAssemblyBegin(). 5218 5219 Collective on Mat 5220 5221 Input Parameters: 5222 + mat - the matrix 5223 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5224 5225 Options Database Keys: 5226 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5227 . -mat_view ::ascii_info_detail - Prints more detailed info 5228 . -mat_view - Prints matrix in ASCII format 5229 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5230 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5231 . -display <name> - Sets display name (default is host) 5232 . -draw_pause <sec> - Sets number of seconds to pause after display 5233 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab ) 5234 . -viewer_socket_machine <machine> - Machine to use for socket 5235 . -viewer_socket_port <port> - Port number to use for socket 5236 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5237 5238 Notes: 5239 MatSetValues() generally caches the values. The matrix is ready to 5240 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5241 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5242 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5243 using the matrix. 5244 5245 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5246 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5247 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5248 5249 Level: beginner 5250 5251 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5252 @*/ 5253 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5254 { 5255 PetscErrorCode ierr; 5256 static PetscInt inassm = 0; 5257 PetscBool flg = PETSC_FALSE; 5258 5259 PetscFunctionBegin; 5260 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5261 PetscValidType(mat,1); 5262 5263 inassm++; 5264 MatAssemblyEnd_InUse++; 5265 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5266 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5267 if (mat->ops->assemblyend) { 5268 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5269 } 5270 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5271 } else if (mat->ops->assemblyend) { 5272 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5273 } 5274 5275 /* Flush assembly is not a true assembly */ 5276 if (type != MAT_FLUSH_ASSEMBLY) { 5277 mat->num_ass++; 5278 mat->assembled = PETSC_TRUE; 5279 mat->ass_nonzerostate = mat->nonzerostate; 5280 } 5281 5282 mat->insertmode = NOT_SET_VALUES; 5283 MatAssemblyEnd_InUse--; 5284 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5285 if (!mat->symmetric_eternal) { 5286 mat->symmetric_set = PETSC_FALSE; 5287 mat->hermitian_set = PETSC_FALSE; 5288 mat->structurally_symmetric_set = PETSC_FALSE; 5289 } 5290 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5291 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5292 5293 if (mat->checksymmetryonassembly) { 5294 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5295 if (flg) { 5296 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5297 } else { 5298 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5299 } 5300 } 5301 if (mat->nullsp && mat->checknullspaceonassembly) { 5302 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5303 } 5304 } 5305 inassm--; 5306 PetscFunctionReturn(0); 5307 } 5308 5309 /*@ 5310 MatSetOption - Sets a parameter option for a matrix. Some options 5311 may be specific to certain storage formats. Some options 5312 determine how values will be inserted (or added). Sorted, 5313 row-oriented input will generally assemble the fastest. The default 5314 is row-oriented. 5315 5316 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5317 5318 Input Parameters: 5319 + mat - the matrix 5320 . option - the option, one of those listed below (and possibly others), 5321 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5322 5323 Options Describing Matrix Structure: 5324 + MAT_SPD - symmetric positive definite 5325 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5326 . MAT_HERMITIAN - transpose is the complex conjugation 5327 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5328 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5329 you set to be kept with all future use of the matrix 5330 including after MatAssemblyBegin/End() which could 5331 potentially change the symmetry structure, i.e. you 5332 KNOW the matrix will ALWAYS have the property you set. 5333 5334 5335 Options For Use with MatSetValues(): 5336 Insert a logically dense subblock, which can be 5337 . MAT_ROW_ORIENTED - row-oriented (default) 5338 5339 Note these options reflect the data you pass in with MatSetValues(); it has 5340 nothing to do with how the data is stored internally in the matrix 5341 data structure. 5342 5343 When (re)assembling a matrix, we can restrict the input for 5344 efficiency/debugging purposes. These options include: 5345 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5346 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 5347 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5348 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5349 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5350 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5351 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5352 performance for very large process counts. 5353 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5354 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5355 functions, instead sending only neighbor messages. 5356 5357 Notes: 5358 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5359 5360 Some options are relevant only for particular matrix types and 5361 are thus ignored by others. Other options are not supported by 5362 certain matrix types and will generate an error message if set. 5363 5364 If using a Fortran 77 module to compute a matrix, one may need to 5365 use the column-oriented option (or convert to the row-oriented 5366 format). 5367 5368 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5369 that would generate a new entry in the nonzero structure is instead 5370 ignored. Thus, if memory has not alredy been allocated for this particular 5371 data, then the insertion is ignored. For dense matrices, in which 5372 the entire array is allocated, no entries are ever ignored. 5373 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5374 5375 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5376 that would generate a new entry in the nonzero structure instead produces 5377 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 5378 5379 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5380 that would generate a new entry that has not been preallocated will 5381 instead produce an error. (Currently supported for AIJ and BAIJ formats 5382 only.) This is a useful flag when debugging matrix memory preallocation. 5383 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5384 5385 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5386 other processors should be dropped, rather than stashed. 5387 This is useful if you know that the "owning" processor is also 5388 always generating the correct matrix entries, so that PETSc need 5389 not transfer duplicate entries generated on another processor. 5390 5391 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5392 searches during matrix assembly. When this flag is set, the hash table 5393 is created during the first Matrix Assembly. This hash table is 5394 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5395 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5396 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5397 supported by MATMPIBAIJ format only. 5398 5399 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5400 are kept in the nonzero structure 5401 5402 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5403 a zero location in the matrix 5404 5405 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5406 5407 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5408 zero row routines and thus improves performance for very large process counts. 5409 5410 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5411 part of the matrix (since they should match the upper triangular part). 5412 5413 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5414 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5415 with finite difference schemes with non-periodic boundary conditions. 5416 Notes: 5417 Can only be called after MatSetSizes() and MatSetType() have been set. 5418 5419 Level: intermediate 5420 5421 .seealso: MatOption, Mat 5422 5423 @*/ 5424 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5425 { 5426 PetscErrorCode ierr; 5427 5428 PetscFunctionBegin; 5429 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5430 PetscValidType(mat,1); 5431 if (op > 0) { 5432 PetscValidLogicalCollectiveEnum(mat,op,2); 5433 PetscValidLogicalCollectiveBool(mat,flg,3); 5434 } 5435 5436 if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op); 5437 if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot set options until type and size have been set, see MatSetType() and MatSetSizes()"); 5438 5439 switch (op) { 5440 case MAT_NO_OFF_PROC_ENTRIES: 5441 mat->nooffprocentries = flg; 5442 PetscFunctionReturn(0); 5443 break; 5444 case MAT_SUBSET_OFF_PROC_ENTRIES: 5445 mat->assembly_subset = flg; 5446 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5447 #if !defined(PETSC_HAVE_MPIUNI) 5448 ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr); 5449 #endif 5450 mat->stash.first_assembly_done = PETSC_FALSE; 5451 } 5452 PetscFunctionReturn(0); 5453 case MAT_NO_OFF_PROC_ZERO_ROWS: 5454 mat->nooffproczerorows = flg; 5455 PetscFunctionReturn(0); 5456 break; 5457 case MAT_SPD: 5458 mat->spd_set = PETSC_TRUE; 5459 mat->spd = flg; 5460 if (flg) { 5461 mat->symmetric = PETSC_TRUE; 5462 mat->structurally_symmetric = PETSC_TRUE; 5463 mat->symmetric_set = PETSC_TRUE; 5464 mat->structurally_symmetric_set = PETSC_TRUE; 5465 } 5466 break; 5467 case MAT_SYMMETRIC: 5468 mat->symmetric = flg; 5469 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5470 mat->symmetric_set = PETSC_TRUE; 5471 mat->structurally_symmetric_set = flg; 5472 #if !defined(PETSC_USE_COMPLEX) 5473 mat->hermitian = flg; 5474 mat->hermitian_set = PETSC_TRUE; 5475 #endif 5476 break; 5477 case MAT_HERMITIAN: 5478 mat->hermitian = flg; 5479 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5480 mat->hermitian_set = PETSC_TRUE; 5481 mat->structurally_symmetric_set = flg; 5482 #if !defined(PETSC_USE_COMPLEX) 5483 mat->symmetric = flg; 5484 mat->symmetric_set = PETSC_TRUE; 5485 #endif 5486 break; 5487 case MAT_STRUCTURALLY_SYMMETRIC: 5488 mat->structurally_symmetric = flg; 5489 mat->structurally_symmetric_set = PETSC_TRUE; 5490 break; 5491 case MAT_SYMMETRY_ETERNAL: 5492 mat->symmetric_eternal = flg; 5493 break; 5494 case MAT_STRUCTURE_ONLY: 5495 mat->structure_only = flg; 5496 break; 5497 case MAT_SORTED_FULL: 5498 mat->sortedfull = flg; 5499 break; 5500 default: 5501 break; 5502 } 5503 if (mat->ops->setoption) { 5504 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5505 } 5506 PetscFunctionReturn(0); 5507 } 5508 5509 /*@ 5510 MatGetOption - Gets a parameter option that has been set for a matrix. 5511 5512 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5513 5514 Input Parameters: 5515 + mat - the matrix 5516 - option - the option, this only responds to certain options, check the code for which ones 5517 5518 Output Parameter: 5519 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5520 5521 Notes: 5522 Can only be called after MatSetSizes() and MatSetType() have been set. 5523 5524 Level: intermediate 5525 5526 .seealso: MatOption, MatSetOption() 5527 5528 @*/ 5529 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5530 { 5531 PetscFunctionBegin; 5532 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5533 PetscValidType(mat,1); 5534 5535 if (((int) op) <= MAT_OPTION_MIN || ((int) op) >= MAT_OPTION_MAX) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Options %d is out of range",(int)op); 5536 if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()"); 5537 5538 switch (op) { 5539 case MAT_NO_OFF_PROC_ENTRIES: 5540 *flg = mat->nooffprocentries; 5541 break; 5542 case MAT_NO_OFF_PROC_ZERO_ROWS: 5543 *flg = mat->nooffproczerorows; 5544 break; 5545 case MAT_SYMMETRIC: 5546 *flg = mat->symmetric; 5547 break; 5548 case MAT_HERMITIAN: 5549 *flg = mat->hermitian; 5550 break; 5551 case MAT_STRUCTURALLY_SYMMETRIC: 5552 *flg = mat->structurally_symmetric; 5553 break; 5554 case MAT_SYMMETRY_ETERNAL: 5555 *flg = mat->symmetric_eternal; 5556 break; 5557 case MAT_SPD: 5558 *flg = mat->spd; 5559 break; 5560 default: 5561 break; 5562 } 5563 PetscFunctionReturn(0); 5564 } 5565 5566 /*@ 5567 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5568 this routine retains the old nonzero structure. 5569 5570 Logically Collective on Mat 5571 5572 Input Parameters: 5573 . mat - the matrix 5574 5575 Level: intermediate 5576 5577 Notes: 5578 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. 5579 See the Performance chapter of the users manual for information on preallocating matrices. 5580 5581 .seealso: MatZeroRows() 5582 @*/ 5583 PetscErrorCode MatZeroEntries(Mat mat) 5584 { 5585 PetscErrorCode ierr; 5586 5587 PetscFunctionBegin; 5588 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5589 PetscValidType(mat,1); 5590 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5591 if (mat->insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for matrices where you have set values but not yet assembled"); 5592 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5593 MatCheckPreallocated(mat,1); 5594 5595 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5596 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5597 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5598 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5599 PetscFunctionReturn(0); 5600 } 5601 5602 /*@ 5603 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5604 of a set of rows and columns of a matrix. 5605 5606 Collective on Mat 5607 5608 Input Parameters: 5609 + mat - the matrix 5610 . numRows - the number of rows to remove 5611 . rows - the global row indices 5612 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5613 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5614 - b - optional vector of right hand side, that will be adjusted by provided solution 5615 5616 Notes: 5617 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5618 5619 The user can set a value in the diagonal entry (or for the AIJ and 5620 row formats can optionally remove the main diagonal entry from the 5621 nonzero structure as well, by passing 0.0 as the final argument). 5622 5623 For the parallel case, all processes that share the matrix (i.e., 5624 those in the communicator used for matrix creation) MUST call this 5625 routine, regardless of whether any rows being zeroed are owned by 5626 them. 5627 5628 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5629 list only rows local to itself). 5630 5631 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5632 5633 Level: intermediate 5634 5635 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5636 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5637 @*/ 5638 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5639 { 5640 PetscErrorCode ierr; 5641 5642 PetscFunctionBegin; 5643 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5644 PetscValidType(mat,1); 5645 if (numRows) PetscValidIntPointer(rows,3); 5646 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5647 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5648 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5649 MatCheckPreallocated(mat,1); 5650 5651 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5652 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5653 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5654 PetscFunctionReturn(0); 5655 } 5656 5657 /*@ 5658 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5659 of a set of rows and columns of a matrix. 5660 5661 Collective on Mat 5662 5663 Input Parameters: 5664 + mat - the matrix 5665 . is - the rows to zero 5666 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5667 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5668 - b - optional vector of right hand side, that will be adjusted by provided solution 5669 5670 Notes: 5671 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5672 5673 The user can set a value in the diagonal entry (or for the AIJ and 5674 row formats can optionally remove the main diagonal entry from the 5675 nonzero structure as well, by passing 0.0 as the final argument). 5676 5677 For the parallel case, all processes that share the matrix (i.e., 5678 those in the communicator used for matrix creation) MUST call this 5679 routine, regardless of whether any rows being zeroed are owned by 5680 them. 5681 5682 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5683 list only rows local to itself). 5684 5685 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5686 5687 Level: intermediate 5688 5689 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5690 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 5691 @*/ 5692 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5693 { 5694 PetscErrorCode ierr; 5695 PetscInt numRows; 5696 const PetscInt *rows; 5697 5698 PetscFunctionBegin; 5699 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5700 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5701 PetscValidType(mat,1); 5702 PetscValidType(is,2); 5703 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5704 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5705 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5706 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5707 PetscFunctionReturn(0); 5708 } 5709 5710 /*@ 5711 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5712 of a set of rows of a matrix. 5713 5714 Collective on Mat 5715 5716 Input Parameters: 5717 + mat - the matrix 5718 . numRows - the number of rows to remove 5719 . rows - the global row indices 5720 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5721 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5722 - b - optional vector of right hand side, that will be adjusted by provided solution 5723 5724 Notes: 5725 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5726 but does not release memory. For the dense and block diagonal 5727 formats this does not alter the nonzero structure. 5728 5729 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5730 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5731 merely zeroed. 5732 5733 The user can set a value in the diagonal entry (or for the AIJ and 5734 row formats can optionally remove the main diagonal entry from the 5735 nonzero structure as well, by passing 0.0 as the final argument). 5736 5737 For the parallel case, all processes that share the matrix (i.e., 5738 those in the communicator used for matrix creation) MUST call this 5739 routine, regardless of whether any rows being zeroed are owned by 5740 them. 5741 5742 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5743 list only rows local to itself). 5744 5745 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5746 owns that are to be zeroed. This saves a global synchronization in the implementation. 5747 5748 Level: intermediate 5749 5750 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5751 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5752 @*/ 5753 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5754 { 5755 PetscErrorCode ierr; 5756 5757 PetscFunctionBegin; 5758 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5759 PetscValidType(mat,1); 5760 if (numRows) PetscValidIntPointer(rows,3); 5761 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5762 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5763 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5764 MatCheckPreallocated(mat,1); 5765 5766 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5767 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5768 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5769 PetscFunctionReturn(0); 5770 } 5771 5772 /*@ 5773 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5774 of a set of rows of a matrix. 5775 5776 Collective on Mat 5777 5778 Input Parameters: 5779 + mat - the matrix 5780 . is - index set of rows to remove 5781 . diag - value put in all diagonals of eliminated rows 5782 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5783 - b - optional vector of right hand side, that will be adjusted by provided solution 5784 5785 Notes: 5786 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5787 but does not release memory. For the dense and block diagonal 5788 formats this does not alter the nonzero structure. 5789 5790 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5791 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5792 merely zeroed. 5793 5794 The user can set a value in the diagonal entry (or for the AIJ and 5795 row formats can optionally remove the main diagonal entry from the 5796 nonzero structure as well, by passing 0.0 as the final argument). 5797 5798 For the parallel case, all processes that share the matrix (i.e., 5799 those in the communicator used for matrix creation) MUST call this 5800 routine, regardless of whether any rows being zeroed are owned by 5801 them. 5802 5803 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5804 list only rows local to itself). 5805 5806 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5807 owns that are to be zeroed. This saves a global synchronization in the implementation. 5808 5809 Level: intermediate 5810 5811 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5812 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5813 @*/ 5814 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5815 { 5816 PetscInt numRows; 5817 const PetscInt *rows; 5818 PetscErrorCode ierr; 5819 5820 PetscFunctionBegin; 5821 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5822 PetscValidType(mat,1); 5823 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5824 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5825 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5826 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5827 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5828 PetscFunctionReturn(0); 5829 } 5830 5831 /*@ 5832 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 5833 of a set of rows of a matrix. These rows must be local to the process. 5834 5835 Collective on Mat 5836 5837 Input Parameters: 5838 + mat - the matrix 5839 . numRows - the number of rows to remove 5840 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5841 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5842 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5843 - b - optional vector of right hand side, that will be adjusted by provided solution 5844 5845 Notes: 5846 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5847 but does not release memory. For the dense and block diagonal 5848 formats this does not alter the nonzero structure. 5849 5850 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5851 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5852 merely zeroed. 5853 5854 The user can set a value in the diagonal entry (or for the AIJ and 5855 row formats can optionally remove the main diagonal entry from the 5856 nonzero structure as well, by passing 0.0 as the final argument). 5857 5858 For the parallel case, all processes that share the matrix (i.e., 5859 those in the communicator used for matrix creation) MUST call this 5860 routine, regardless of whether any rows being zeroed are owned by 5861 them. 5862 5863 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5864 list only rows local to itself). 5865 5866 The grid coordinates are across the entire grid, not just the local portion 5867 5868 In Fortran idxm and idxn should be declared as 5869 $ MatStencil idxm(4,m) 5870 and the values inserted using 5871 $ idxm(MatStencil_i,1) = i 5872 $ idxm(MatStencil_j,1) = j 5873 $ idxm(MatStencil_k,1) = k 5874 $ idxm(MatStencil_c,1) = c 5875 etc 5876 5877 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5878 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5879 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5880 DM_BOUNDARY_PERIODIC boundary type. 5881 5882 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 5883 a single value per point) you can skip filling those indices. 5884 5885 Level: intermediate 5886 5887 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5888 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5889 @*/ 5890 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5891 { 5892 PetscInt dim = mat->stencil.dim; 5893 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5894 PetscInt *dims = mat->stencil.dims+1; 5895 PetscInt *starts = mat->stencil.starts; 5896 PetscInt *dxm = (PetscInt*) rows; 5897 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5898 PetscErrorCode ierr; 5899 5900 PetscFunctionBegin; 5901 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5902 PetscValidType(mat,1); 5903 if (numRows) PetscValidIntPointer(rows,3); 5904 5905 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 5906 for (i = 0; i < numRows; ++i) { 5907 /* Skip unused dimensions (they are ordered k, j, i, c) */ 5908 for (j = 0; j < 3-sdim; ++j) dxm++; 5909 /* Local index in X dir */ 5910 tmp = *dxm++ - starts[0]; 5911 /* Loop over remaining dimensions */ 5912 for (j = 0; j < dim-1; ++j) { 5913 /* If nonlocal, set index to be negative */ 5914 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 5915 /* Update local index */ 5916 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 5917 } 5918 /* Skip component slot if necessary */ 5919 if (mat->stencil.noc) dxm++; 5920 /* Local row number */ 5921 if (tmp >= 0) { 5922 jdxm[numNewRows++] = tmp; 5923 } 5924 } 5925 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 5926 ierr = PetscFree(jdxm);CHKERRQ(ierr); 5927 PetscFunctionReturn(0); 5928 } 5929 5930 /*@ 5931 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 5932 of a set of rows and columns of a matrix. 5933 5934 Collective on Mat 5935 5936 Input Parameters: 5937 + mat - the matrix 5938 . numRows - the number of rows/columns to remove 5939 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5940 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5941 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5942 - b - optional vector of right hand side, that will be adjusted by provided solution 5943 5944 Notes: 5945 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5946 but does not release memory. For the dense and block diagonal 5947 formats this does not alter the nonzero structure. 5948 5949 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5950 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5951 merely zeroed. 5952 5953 The user can set a value in the diagonal entry (or for the AIJ and 5954 row formats can optionally remove the main diagonal entry from the 5955 nonzero structure as well, by passing 0.0 as the final argument). 5956 5957 For the parallel case, all processes that share the matrix (i.e., 5958 those in the communicator used for matrix creation) MUST call this 5959 routine, regardless of whether any rows being zeroed are owned by 5960 them. 5961 5962 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5963 list only rows local to itself, but the row/column numbers are given in local numbering). 5964 5965 The grid coordinates are across the entire grid, not just the local portion 5966 5967 In Fortran idxm and idxn should be declared as 5968 $ MatStencil idxm(4,m) 5969 and the values inserted using 5970 $ idxm(MatStencil_i,1) = i 5971 $ idxm(MatStencil_j,1) = j 5972 $ idxm(MatStencil_k,1) = k 5973 $ idxm(MatStencil_c,1) = c 5974 etc 5975 5976 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5977 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5978 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5979 DM_BOUNDARY_PERIODIC boundary type. 5980 5981 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 5982 a single value per point) you can skip filling those indices. 5983 5984 Level: intermediate 5985 5986 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5987 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 5988 @*/ 5989 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5990 { 5991 PetscInt dim = mat->stencil.dim; 5992 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5993 PetscInt *dims = mat->stencil.dims+1; 5994 PetscInt *starts = mat->stencil.starts; 5995 PetscInt *dxm = (PetscInt*) rows; 5996 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5997 PetscErrorCode ierr; 5998 5999 PetscFunctionBegin; 6000 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6001 PetscValidType(mat,1); 6002 if (numRows) PetscValidIntPointer(rows,3); 6003 6004 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6005 for (i = 0; i < numRows; ++i) { 6006 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6007 for (j = 0; j < 3-sdim; ++j) dxm++; 6008 /* Local index in X dir */ 6009 tmp = *dxm++ - starts[0]; 6010 /* Loop over remaining dimensions */ 6011 for (j = 0; j < dim-1; ++j) { 6012 /* If nonlocal, set index to be negative */ 6013 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6014 /* Update local index */ 6015 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6016 } 6017 /* Skip component slot if necessary */ 6018 if (mat->stencil.noc) dxm++; 6019 /* Local row number */ 6020 if (tmp >= 0) { 6021 jdxm[numNewRows++] = tmp; 6022 } 6023 } 6024 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6025 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6026 PetscFunctionReturn(0); 6027 } 6028 6029 /*@C 6030 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6031 of a set of rows of a matrix; using local numbering of rows. 6032 6033 Collective on Mat 6034 6035 Input Parameters: 6036 + mat - the matrix 6037 . numRows - the number of rows to remove 6038 . rows - the global row indices 6039 . diag - value put in all diagonals of eliminated rows 6040 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6041 - b - optional vector of right hand side, that will be adjusted by provided solution 6042 6043 Notes: 6044 Before calling MatZeroRowsLocal(), the user must first set the 6045 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6046 6047 For the AIJ matrix formats this removes the old nonzero structure, 6048 but does not release memory. For the dense and block diagonal 6049 formats this does not alter the nonzero structure. 6050 6051 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6052 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6053 merely zeroed. 6054 6055 The user can set a value in the diagonal entry (or for the AIJ and 6056 row formats can optionally remove the main diagonal entry from the 6057 nonzero structure as well, by passing 0.0 as the final argument). 6058 6059 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6060 owns that are to be zeroed. This saves a global synchronization in the implementation. 6061 6062 Level: intermediate 6063 6064 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6065 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6066 @*/ 6067 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6068 { 6069 PetscErrorCode ierr; 6070 6071 PetscFunctionBegin; 6072 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6073 PetscValidType(mat,1); 6074 if (numRows) PetscValidIntPointer(rows,3); 6075 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6076 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6077 MatCheckPreallocated(mat,1); 6078 6079 if (mat->ops->zerorowslocal) { 6080 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6081 } else { 6082 IS is, newis; 6083 const PetscInt *newRows; 6084 6085 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6086 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6087 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 6088 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6089 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6090 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6091 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6092 ierr = ISDestroy(&is);CHKERRQ(ierr); 6093 } 6094 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6095 PetscFunctionReturn(0); 6096 } 6097 6098 /*@ 6099 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6100 of a set of rows of a matrix; using local numbering of rows. 6101 6102 Collective on Mat 6103 6104 Input Parameters: 6105 + mat - the matrix 6106 . is - index set of rows to remove 6107 . diag - value put in all diagonals of eliminated rows 6108 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6109 - b - optional vector of right hand side, that will be adjusted by provided solution 6110 6111 Notes: 6112 Before calling MatZeroRowsLocalIS(), the user must first set the 6113 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6114 6115 For the AIJ matrix formats this removes the old nonzero structure, 6116 but does not release memory. For the dense and block diagonal 6117 formats this does not alter the nonzero structure. 6118 6119 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6120 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6121 merely zeroed. 6122 6123 The user can set a value in the diagonal entry (or for the AIJ and 6124 row formats can optionally remove the main diagonal entry from the 6125 nonzero structure as well, by passing 0.0 as the final argument). 6126 6127 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6128 owns that are to be zeroed. This saves a global synchronization in the implementation. 6129 6130 Level: intermediate 6131 6132 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6133 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6134 @*/ 6135 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6136 { 6137 PetscErrorCode ierr; 6138 PetscInt numRows; 6139 const PetscInt *rows; 6140 6141 PetscFunctionBegin; 6142 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6143 PetscValidType(mat,1); 6144 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6145 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6146 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6147 MatCheckPreallocated(mat,1); 6148 6149 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6150 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6151 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6152 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6153 PetscFunctionReturn(0); 6154 } 6155 6156 /*@ 6157 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6158 of a set of rows and columns of a matrix; using local numbering of rows. 6159 6160 Collective on Mat 6161 6162 Input Parameters: 6163 + mat - the matrix 6164 . numRows - the number of rows to remove 6165 . rows - the global row indices 6166 . diag - value put in all diagonals of eliminated rows 6167 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6168 - b - optional vector of right hand side, that will be adjusted by provided solution 6169 6170 Notes: 6171 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6172 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6173 6174 The user can set a value in the diagonal entry (or for the AIJ and 6175 row formats can optionally remove the main diagonal entry from the 6176 nonzero structure as well, by passing 0.0 as the final argument). 6177 6178 Level: intermediate 6179 6180 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6181 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6182 @*/ 6183 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6184 { 6185 PetscErrorCode ierr; 6186 IS is, newis; 6187 const PetscInt *newRows; 6188 6189 PetscFunctionBegin; 6190 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6191 PetscValidType(mat,1); 6192 if (numRows) PetscValidIntPointer(rows,3); 6193 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6194 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6195 MatCheckPreallocated(mat,1); 6196 6197 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6198 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6199 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6200 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6201 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6202 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6203 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6204 ierr = ISDestroy(&is);CHKERRQ(ierr); 6205 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6206 PetscFunctionReturn(0); 6207 } 6208 6209 /*@ 6210 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6211 of a set of rows and columns of a matrix; using local numbering of rows. 6212 6213 Collective on Mat 6214 6215 Input Parameters: 6216 + mat - the matrix 6217 . is - index set of rows to remove 6218 . diag - value put in all diagonals of eliminated rows 6219 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6220 - b - optional vector of right hand side, that will be adjusted by provided solution 6221 6222 Notes: 6223 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6224 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6225 6226 The user can set a value in the diagonal entry (or for the AIJ and 6227 row formats can optionally remove the main diagonal entry from the 6228 nonzero structure as well, by passing 0.0 as the final argument). 6229 6230 Level: intermediate 6231 6232 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6233 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6234 @*/ 6235 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6236 { 6237 PetscErrorCode ierr; 6238 PetscInt numRows; 6239 const PetscInt *rows; 6240 6241 PetscFunctionBegin; 6242 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6243 PetscValidType(mat,1); 6244 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6245 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6246 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6247 MatCheckPreallocated(mat,1); 6248 6249 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6250 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6251 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6252 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6253 PetscFunctionReturn(0); 6254 } 6255 6256 /*@C 6257 MatGetSize - Returns the numbers of rows and columns in a matrix. 6258 6259 Not Collective 6260 6261 Input Parameter: 6262 . mat - the matrix 6263 6264 Output Parameters: 6265 + m - the number of global rows 6266 - n - the number of global columns 6267 6268 Note: both output parameters can be NULL on input. 6269 6270 Level: beginner 6271 6272 .seealso: MatGetLocalSize() 6273 @*/ 6274 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6275 { 6276 PetscFunctionBegin; 6277 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6278 if (m) *m = mat->rmap->N; 6279 if (n) *n = mat->cmap->N; 6280 PetscFunctionReturn(0); 6281 } 6282 6283 /*@C 6284 MatGetLocalSize - Returns the number of rows and columns in a matrix 6285 stored locally. This information may be implementation dependent, so 6286 use with care. 6287 6288 Not Collective 6289 6290 Input Parameters: 6291 . mat - the matrix 6292 6293 Output Parameters: 6294 + m - the number of local rows 6295 - n - the number of local columns 6296 6297 Note: both output parameters can be NULL on input. 6298 6299 Level: beginner 6300 6301 .seealso: MatGetSize() 6302 @*/ 6303 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6304 { 6305 PetscFunctionBegin; 6306 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6307 if (m) PetscValidIntPointer(m,2); 6308 if (n) PetscValidIntPointer(n,3); 6309 if (m) *m = mat->rmap->n; 6310 if (n) *n = mat->cmap->n; 6311 PetscFunctionReturn(0); 6312 } 6313 6314 /*@C 6315 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6316 this processor. (The columns of the "diagonal block") 6317 6318 Not Collective, unless matrix has not been allocated, then collective on Mat 6319 6320 Input Parameters: 6321 . mat - the matrix 6322 6323 Output Parameters: 6324 + m - the global index of the first local column 6325 - n - one more than the global index of the last local column 6326 6327 Notes: 6328 both output parameters can be NULL on input. 6329 6330 Level: developer 6331 6332 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6333 6334 @*/ 6335 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6336 { 6337 PetscFunctionBegin; 6338 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6339 PetscValidType(mat,1); 6340 if (m) PetscValidIntPointer(m,2); 6341 if (n) PetscValidIntPointer(n,3); 6342 MatCheckPreallocated(mat,1); 6343 if (m) *m = mat->cmap->rstart; 6344 if (n) *n = mat->cmap->rend; 6345 PetscFunctionReturn(0); 6346 } 6347 6348 /*@C 6349 MatGetOwnershipRange - Returns the range of matrix rows owned by 6350 this processor, assuming that the matrix is laid out with the first 6351 n1 rows on the first processor, the next n2 rows on the second, etc. 6352 For certain parallel layouts this range may not be well defined. 6353 6354 Not Collective 6355 6356 Input Parameters: 6357 . mat - the matrix 6358 6359 Output Parameters: 6360 + m - the global index of the first local row 6361 - n - one more than the global index of the last local row 6362 6363 Note: Both output parameters can be NULL on input. 6364 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6365 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6366 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6367 6368 Level: beginner 6369 6370 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6371 6372 @*/ 6373 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6374 { 6375 PetscFunctionBegin; 6376 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6377 PetscValidType(mat,1); 6378 if (m) PetscValidIntPointer(m,2); 6379 if (n) PetscValidIntPointer(n,3); 6380 MatCheckPreallocated(mat,1); 6381 if (m) *m = mat->rmap->rstart; 6382 if (n) *n = mat->rmap->rend; 6383 PetscFunctionReturn(0); 6384 } 6385 6386 /*@C 6387 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6388 each process 6389 6390 Not Collective, unless matrix has not been allocated, then collective on Mat 6391 6392 Input Parameters: 6393 . mat - the matrix 6394 6395 Output Parameters: 6396 . ranges - start of each processors portion plus one more than the total length at the end 6397 6398 Level: beginner 6399 6400 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6401 6402 @*/ 6403 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6404 { 6405 PetscErrorCode ierr; 6406 6407 PetscFunctionBegin; 6408 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6409 PetscValidType(mat,1); 6410 MatCheckPreallocated(mat,1); 6411 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6412 PetscFunctionReturn(0); 6413 } 6414 6415 /*@C 6416 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6417 this processor. (The columns of the "diagonal blocks" for each process) 6418 6419 Not Collective, unless matrix has not been allocated, then collective on Mat 6420 6421 Input Parameters: 6422 . mat - the matrix 6423 6424 Output Parameters: 6425 . ranges - start of each processors portion plus one more then the total length at the end 6426 6427 Level: beginner 6428 6429 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6430 6431 @*/ 6432 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6433 { 6434 PetscErrorCode ierr; 6435 6436 PetscFunctionBegin; 6437 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6438 PetscValidType(mat,1); 6439 MatCheckPreallocated(mat,1); 6440 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6441 PetscFunctionReturn(0); 6442 } 6443 6444 /*@C 6445 MatGetOwnershipIS - Get row and column ownership as index sets 6446 6447 Not Collective 6448 6449 Input Arguments: 6450 . A - matrix of type Elemental 6451 6452 Output Arguments: 6453 + rows - rows in which this process owns elements 6454 - cols - columns in which this process owns elements 6455 6456 Level: intermediate 6457 6458 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL 6459 @*/ 6460 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6461 { 6462 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6463 6464 PetscFunctionBegin; 6465 MatCheckPreallocated(A,1); 6466 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6467 if (f) { 6468 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6469 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6470 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6471 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6472 } 6473 PetscFunctionReturn(0); 6474 } 6475 6476 /*@C 6477 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6478 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6479 to complete the factorization. 6480 6481 Collective on Mat 6482 6483 Input Parameters: 6484 + mat - the matrix 6485 . row - row permutation 6486 . column - column permutation 6487 - info - structure containing 6488 $ levels - number of levels of fill. 6489 $ expected fill - as ratio of original fill. 6490 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6491 missing diagonal entries) 6492 6493 Output Parameters: 6494 . fact - new matrix that has been symbolically factored 6495 6496 Notes: 6497 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6498 6499 Most users should employ the simplified KSP interface for linear solvers 6500 instead of working directly with matrix algebra routines such as this. 6501 See, e.g., KSPCreate(). 6502 6503 Level: developer 6504 6505 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6506 MatGetOrdering(), MatFactorInfo 6507 6508 Note: this uses the definition of level of fill as in Y. Saad, 2003 6509 6510 Developer Note: fortran interface is not autogenerated as the f90 6511 interface defintion cannot be generated correctly [due to MatFactorInfo] 6512 6513 References: 6514 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6515 @*/ 6516 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6517 { 6518 PetscErrorCode ierr; 6519 6520 PetscFunctionBegin; 6521 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6522 PetscValidType(mat,1); 6523 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6524 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6525 PetscValidPointer(info,4); 6526 PetscValidPointer(fact,5); 6527 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6528 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6529 if (!(fact)->ops->ilufactorsymbolic) { 6530 MatSolverType spackage; 6531 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6532 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6533 } 6534 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6535 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6536 MatCheckPreallocated(mat,2); 6537 6538 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6539 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6540 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6541 PetscFunctionReturn(0); 6542 } 6543 6544 /*@C 6545 MatICCFactorSymbolic - Performs symbolic incomplete 6546 Cholesky factorization for a symmetric matrix. Use 6547 MatCholeskyFactorNumeric() to complete the factorization. 6548 6549 Collective on Mat 6550 6551 Input Parameters: 6552 + mat - the matrix 6553 . perm - row and column permutation 6554 - info - structure containing 6555 $ levels - number of levels of fill. 6556 $ expected fill - as ratio of original fill. 6557 6558 Output Parameter: 6559 . fact - the factored matrix 6560 6561 Notes: 6562 Most users should employ the KSP interface for linear solvers 6563 instead of working directly with matrix algebra routines such as this. 6564 See, e.g., KSPCreate(). 6565 6566 Level: developer 6567 6568 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6569 6570 Note: this uses the definition of level of fill as in Y. Saad, 2003 6571 6572 Developer Note: fortran interface is not autogenerated as the f90 6573 interface defintion cannot be generated correctly [due to MatFactorInfo] 6574 6575 References: 6576 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6577 @*/ 6578 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6579 { 6580 PetscErrorCode ierr; 6581 6582 PetscFunctionBegin; 6583 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6584 PetscValidType(mat,1); 6585 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6586 PetscValidPointer(info,3); 6587 PetscValidPointer(fact,4); 6588 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6589 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6590 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6591 if (!(fact)->ops->iccfactorsymbolic) { 6592 MatSolverType spackage; 6593 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6594 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6595 } 6596 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6597 MatCheckPreallocated(mat,2); 6598 6599 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6600 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6601 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6602 PetscFunctionReturn(0); 6603 } 6604 6605 /*@C 6606 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6607 points to an array of valid matrices, they may be reused to store the new 6608 submatrices. 6609 6610 Collective on Mat 6611 6612 Input Parameters: 6613 + mat - the matrix 6614 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6615 . irow, icol - index sets of rows and columns to extract 6616 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6617 6618 Output Parameter: 6619 . submat - the array of submatrices 6620 6621 Notes: 6622 MatCreateSubMatrices() can extract ONLY sequential submatrices 6623 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6624 to extract a parallel submatrix. 6625 6626 Some matrix types place restrictions on the row and column 6627 indices, such as that they be sorted or that they be equal to each other. 6628 6629 The index sets may not have duplicate entries. 6630 6631 When extracting submatrices from a parallel matrix, each processor can 6632 form a different submatrix by setting the rows and columns of its 6633 individual index sets according to the local submatrix desired. 6634 6635 When finished using the submatrices, the user should destroy 6636 them with MatDestroySubMatrices(). 6637 6638 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6639 original matrix has not changed from that last call to MatCreateSubMatrices(). 6640 6641 This routine creates the matrices in submat; you should NOT create them before 6642 calling it. It also allocates the array of matrix pointers submat. 6643 6644 For BAIJ matrices the index sets must respect the block structure, that is if they 6645 request one row/column in a block, they must request all rows/columns that are in 6646 that block. For example, if the block size is 2 you cannot request just row 0 and 6647 column 0. 6648 6649 Fortran Note: 6650 The Fortran interface is slightly different from that given below; it 6651 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6652 6653 Level: advanced 6654 6655 6656 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6657 @*/ 6658 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6659 { 6660 PetscErrorCode ierr; 6661 PetscInt i; 6662 PetscBool eq; 6663 6664 PetscFunctionBegin; 6665 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6666 PetscValidType(mat,1); 6667 if (n) { 6668 PetscValidPointer(irow,3); 6669 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6670 PetscValidPointer(icol,4); 6671 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6672 } 6673 PetscValidPointer(submat,6); 6674 if (n && scall == MAT_REUSE_MATRIX) { 6675 PetscValidPointer(*submat,6); 6676 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6677 } 6678 if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6679 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6680 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6681 MatCheckPreallocated(mat,1); 6682 6683 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6684 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6685 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6686 for (i=0; i<n; i++) { 6687 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6688 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6689 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6690 if (eq) { 6691 if (mat->symmetric) { 6692 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6693 } else if (mat->hermitian) { 6694 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6695 } else if (mat->structurally_symmetric) { 6696 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6697 } 6698 } 6699 } 6700 } 6701 PetscFunctionReturn(0); 6702 } 6703 6704 /*@C 6705 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6706 6707 Collective on Mat 6708 6709 Input Parameters: 6710 + mat - the matrix 6711 . n - the number of submatrixes to be extracted 6712 . irow, icol - index sets of rows and columns to extract 6713 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6714 6715 Output Parameter: 6716 . submat - the array of submatrices 6717 6718 Level: advanced 6719 6720 6721 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6722 @*/ 6723 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6724 { 6725 PetscErrorCode ierr; 6726 PetscInt i; 6727 PetscBool eq; 6728 6729 PetscFunctionBegin; 6730 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6731 PetscValidType(mat,1); 6732 if (n) { 6733 PetscValidPointer(irow,3); 6734 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6735 PetscValidPointer(icol,4); 6736 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6737 } 6738 PetscValidPointer(submat,6); 6739 if (n && scall == MAT_REUSE_MATRIX) { 6740 PetscValidPointer(*submat,6); 6741 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6742 } 6743 if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6744 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6745 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6746 MatCheckPreallocated(mat,1); 6747 6748 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6749 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6750 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6751 for (i=0; i<n; i++) { 6752 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6753 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6754 if (eq) { 6755 if (mat->symmetric) { 6756 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6757 } else if (mat->hermitian) { 6758 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6759 } else if (mat->structurally_symmetric) { 6760 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6761 } 6762 } 6763 } 6764 } 6765 PetscFunctionReturn(0); 6766 } 6767 6768 /*@C 6769 MatDestroyMatrices - Destroys an array of matrices. 6770 6771 Collective on Mat 6772 6773 Input Parameters: 6774 + n - the number of local matrices 6775 - mat - the matrices (note that this is a pointer to the array of matrices) 6776 6777 Level: advanced 6778 6779 Notes: 6780 Frees not only the matrices, but also the array that contains the matrices 6781 In Fortran will not free the array. 6782 6783 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 6784 @*/ 6785 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6786 { 6787 PetscErrorCode ierr; 6788 PetscInt i; 6789 6790 PetscFunctionBegin; 6791 if (!*mat) PetscFunctionReturn(0); 6792 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6793 PetscValidPointer(mat,2); 6794 6795 for (i=0; i<n; i++) { 6796 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 6797 } 6798 6799 /* memory is allocated even if n = 0 */ 6800 ierr = PetscFree(*mat);CHKERRQ(ierr); 6801 PetscFunctionReturn(0); 6802 } 6803 6804 /*@C 6805 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 6806 6807 Collective on Mat 6808 6809 Input Parameters: 6810 + n - the number of local matrices 6811 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6812 sequence of MatCreateSubMatrices()) 6813 6814 Level: advanced 6815 6816 Notes: 6817 Frees not only the matrices, but also the array that contains the matrices 6818 In Fortran will not free the array. 6819 6820 .seealso: MatCreateSubMatrices() 6821 @*/ 6822 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 6823 { 6824 PetscErrorCode ierr; 6825 Mat mat0; 6826 6827 PetscFunctionBegin; 6828 if (!*mat) PetscFunctionReturn(0); 6829 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 6830 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6831 PetscValidPointer(mat,2); 6832 6833 mat0 = (*mat)[0]; 6834 if (mat0 && mat0->ops->destroysubmatrices) { 6835 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr); 6836 } else { 6837 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr); 6838 } 6839 PetscFunctionReturn(0); 6840 } 6841 6842 /*@C 6843 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 6844 6845 Collective on Mat 6846 6847 Input Parameters: 6848 . mat - the matrix 6849 6850 Output Parameter: 6851 . matstruct - the sequential matrix with the nonzero structure of mat 6852 6853 Level: intermediate 6854 6855 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 6856 @*/ 6857 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 6858 { 6859 PetscErrorCode ierr; 6860 6861 PetscFunctionBegin; 6862 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6863 PetscValidPointer(matstruct,2); 6864 6865 PetscValidType(mat,1); 6866 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6867 MatCheckPreallocated(mat,1); 6868 6869 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 6870 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6871 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 6872 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6873 PetscFunctionReturn(0); 6874 } 6875 6876 /*@C 6877 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 6878 6879 Collective on Mat 6880 6881 Input Parameters: 6882 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 6883 sequence of MatGetSequentialNonzeroStructure()) 6884 6885 Level: advanced 6886 6887 Notes: 6888 Frees not only the matrices, but also the array that contains the matrices 6889 6890 .seealso: MatGetSeqNonzeroStructure() 6891 @*/ 6892 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 6893 { 6894 PetscErrorCode ierr; 6895 6896 PetscFunctionBegin; 6897 PetscValidPointer(mat,1); 6898 ierr = MatDestroy(mat);CHKERRQ(ierr); 6899 PetscFunctionReturn(0); 6900 } 6901 6902 /*@ 6903 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 6904 replaces the index sets by larger ones that represent submatrices with 6905 additional overlap. 6906 6907 Collective on Mat 6908 6909 Input Parameters: 6910 + mat - the matrix 6911 . n - the number of index sets 6912 . is - the array of index sets (these index sets will changed during the call) 6913 - ov - the additional overlap requested 6914 6915 Options Database: 6916 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 6917 6918 Level: developer 6919 6920 6921 .seealso: MatCreateSubMatrices() 6922 @*/ 6923 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 6924 { 6925 PetscErrorCode ierr; 6926 6927 PetscFunctionBegin; 6928 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6929 PetscValidType(mat,1); 6930 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 6931 if (n) { 6932 PetscValidPointer(is,3); 6933 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 6934 } 6935 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6936 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6937 MatCheckPreallocated(mat,1); 6938 6939 if (!ov) PetscFunctionReturn(0); 6940 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6941 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6942 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 6943 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6944 PetscFunctionReturn(0); 6945 } 6946 6947 6948 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 6949 6950 /*@ 6951 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 6952 a sub communicator, replaces the index sets by larger ones that represent submatrices with 6953 additional overlap. 6954 6955 Collective on Mat 6956 6957 Input Parameters: 6958 + mat - the matrix 6959 . n - the number of index sets 6960 . is - the array of index sets (these index sets will changed during the call) 6961 - ov - the additional overlap requested 6962 6963 Options Database: 6964 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 6965 6966 Level: developer 6967 6968 6969 .seealso: MatCreateSubMatrices() 6970 @*/ 6971 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 6972 { 6973 PetscInt i; 6974 PetscErrorCode ierr; 6975 6976 PetscFunctionBegin; 6977 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6978 PetscValidType(mat,1); 6979 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 6980 if (n) { 6981 PetscValidPointer(is,3); 6982 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 6983 } 6984 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6985 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6986 MatCheckPreallocated(mat,1); 6987 if (!ov) PetscFunctionReturn(0); 6988 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6989 for(i=0; i<n; i++){ 6990 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 6991 } 6992 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6993 PetscFunctionReturn(0); 6994 } 6995 6996 6997 6998 6999 /*@ 7000 MatGetBlockSize - Returns the matrix block size. 7001 7002 Not Collective 7003 7004 Input Parameter: 7005 . mat - the matrix 7006 7007 Output Parameter: 7008 . bs - block size 7009 7010 Notes: 7011 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7012 7013 If the block size has not been set yet this routine returns 1. 7014 7015 Level: intermediate 7016 7017 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7018 @*/ 7019 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7020 { 7021 PetscFunctionBegin; 7022 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7023 PetscValidIntPointer(bs,2); 7024 *bs = PetscAbs(mat->rmap->bs); 7025 PetscFunctionReturn(0); 7026 } 7027 7028 /*@ 7029 MatGetBlockSizes - Returns the matrix block row and column sizes. 7030 7031 Not Collective 7032 7033 Input Parameter: 7034 . mat - the matrix 7035 7036 Output Parameter: 7037 + rbs - row block size 7038 - cbs - column block size 7039 7040 Notes: 7041 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7042 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7043 7044 If a block size has not been set yet this routine returns 1. 7045 7046 Level: intermediate 7047 7048 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7049 @*/ 7050 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7051 { 7052 PetscFunctionBegin; 7053 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7054 if (rbs) PetscValidIntPointer(rbs,2); 7055 if (cbs) PetscValidIntPointer(cbs,3); 7056 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7057 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7058 PetscFunctionReturn(0); 7059 } 7060 7061 /*@ 7062 MatSetBlockSize - Sets the matrix block size. 7063 7064 Logically Collective on Mat 7065 7066 Input Parameters: 7067 + mat - the matrix 7068 - bs - block size 7069 7070 Notes: 7071 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7072 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7073 7074 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7075 is compatible with the matrix local sizes. 7076 7077 Level: intermediate 7078 7079 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7080 @*/ 7081 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7082 { 7083 PetscErrorCode ierr; 7084 7085 PetscFunctionBegin; 7086 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7087 PetscValidLogicalCollectiveInt(mat,bs,2); 7088 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr); 7089 PetscFunctionReturn(0); 7090 } 7091 7092 /*@ 7093 MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size 7094 7095 Logically Collective on Mat 7096 7097 Input Parameters: 7098 + mat - the matrix 7099 . nblocks - the number of blocks on this process 7100 - bsizes - the block sizes 7101 7102 Notes: 7103 Currently used by PCVPBJACOBI for SeqAIJ matrices 7104 7105 Level: intermediate 7106 7107 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes() 7108 @*/ 7109 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7110 { 7111 PetscErrorCode ierr; 7112 PetscInt i,ncnt = 0, nlocal; 7113 7114 PetscFunctionBegin; 7115 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7116 if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7117 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr); 7118 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7119 if (ncnt != nlocal) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Sum of local block sizes %D does not equal local size of matrix %D",ncnt,nlocal); 7120 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr); 7121 mat->nblocks = nblocks; 7122 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr); 7123 ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr); 7124 PetscFunctionReturn(0); 7125 } 7126 7127 /*@C 7128 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7129 7130 Logically Collective on Mat 7131 7132 Input Parameters: 7133 . mat - the matrix 7134 7135 Output Parameters: 7136 + nblocks - the number of blocks on this process 7137 - bsizes - the block sizes 7138 7139 Notes: Currently not supported from Fortran 7140 7141 Level: intermediate 7142 7143 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7144 @*/ 7145 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7146 { 7147 PetscFunctionBegin; 7148 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7149 *nblocks = mat->nblocks; 7150 *bsizes = mat->bsizes; 7151 PetscFunctionReturn(0); 7152 } 7153 7154 /*@ 7155 MatSetBlockSizes - Sets the matrix block row and column sizes. 7156 7157 Logically Collective on Mat 7158 7159 Input Parameters: 7160 + mat - the matrix 7161 - rbs - row block size 7162 - cbs - column block size 7163 7164 Notes: 7165 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7166 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7167 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 7168 7169 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7170 are compatible with the matrix local sizes. 7171 7172 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7173 7174 Level: intermediate 7175 7176 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7177 @*/ 7178 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7179 { 7180 PetscErrorCode ierr; 7181 7182 PetscFunctionBegin; 7183 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7184 PetscValidLogicalCollectiveInt(mat,rbs,2); 7185 PetscValidLogicalCollectiveInt(mat,cbs,3); 7186 if (mat->ops->setblocksizes) { 7187 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr); 7188 } 7189 if (mat->rmap->refcnt) { 7190 ISLocalToGlobalMapping l2g = NULL; 7191 PetscLayout nmap = NULL; 7192 7193 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr); 7194 if (mat->rmap->mapping) { 7195 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr); 7196 } 7197 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr); 7198 mat->rmap = nmap; 7199 mat->rmap->mapping = l2g; 7200 } 7201 if (mat->cmap->refcnt) { 7202 ISLocalToGlobalMapping l2g = NULL; 7203 PetscLayout nmap = NULL; 7204 7205 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr); 7206 if (mat->cmap->mapping) { 7207 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr); 7208 } 7209 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 7210 mat->cmap = nmap; 7211 mat->cmap->mapping = l2g; 7212 } 7213 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7214 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7215 PetscFunctionReturn(0); 7216 } 7217 7218 /*@ 7219 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7220 7221 Logically Collective on Mat 7222 7223 Input Parameters: 7224 + mat - the matrix 7225 . fromRow - matrix from which to copy row block size 7226 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7227 7228 Level: developer 7229 7230 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7231 @*/ 7232 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7233 { 7234 PetscErrorCode ierr; 7235 7236 PetscFunctionBegin; 7237 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7238 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7239 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7240 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7241 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7242 PetscFunctionReturn(0); 7243 } 7244 7245 /*@ 7246 MatResidual - Default routine to calculate the residual. 7247 7248 Collective on Mat 7249 7250 Input Parameters: 7251 + mat - the matrix 7252 . b - the right-hand-side 7253 - x - the approximate solution 7254 7255 Output Parameter: 7256 . r - location to store the residual 7257 7258 Level: developer 7259 7260 .seealso: PCMGSetResidual() 7261 @*/ 7262 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7263 { 7264 PetscErrorCode ierr; 7265 7266 PetscFunctionBegin; 7267 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7268 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7269 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7270 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7271 PetscValidType(mat,1); 7272 MatCheckPreallocated(mat,1); 7273 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7274 if (!mat->ops->residual) { 7275 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7276 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7277 } else { 7278 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7279 } 7280 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7281 PetscFunctionReturn(0); 7282 } 7283 7284 /*@C 7285 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7286 7287 Collective on Mat 7288 7289 Input Parameters: 7290 + mat - the matrix 7291 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7292 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7293 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7294 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7295 always used. 7296 7297 Output Parameters: 7298 + n - number of rows in the (possibly compressed) matrix 7299 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7300 . ja - the column indices 7301 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7302 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7303 7304 Level: developer 7305 7306 Notes: 7307 You CANNOT change any of the ia[] or ja[] values. 7308 7309 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7310 7311 Fortran Notes: 7312 In Fortran use 7313 $ 7314 $ PetscInt ia(1), ja(1) 7315 $ PetscOffset iia, jja 7316 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7317 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7318 7319 or 7320 $ 7321 $ PetscInt, pointer :: ia(:),ja(:) 7322 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7323 $ ! Access the ith and jth entries via ia(i) and ja(j) 7324 7325 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7326 @*/ 7327 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7328 { 7329 PetscErrorCode ierr; 7330 7331 PetscFunctionBegin; 7332 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7333 PetscValidType(mat,1); 7334 PetscValidIntPointer(n,5); 7335 if (ia) PetscValidIntPointer(ia,6); 7336 if (ja) PetscValidIntPointer(ja,7); 7337 PetscValidIntPointer(done,8); 7338 MatCheckPreallocated(mat,1); 7339 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7340 else { 7341 *done = PETSC_TRUE; 7342 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7343 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7344 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7345 } 7346 PetscFunctionReturn(0); 7347 } 7348 7349 /*@C 7350 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7351 7352 Collective on Mat 7353 7354 Input Parameters: 7355 + mat - the matrix 7356 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7357 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7358 symmetrized 7359 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7360 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7361 always used. 7362 . n - number of columns in the (possibly compressed) matrix 7363 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7364 - ja - the row indices 7365 7366 Output Parameters: 7367 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7368 7369 Level: developer 7370 7371 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7372 @*/ 7373 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7374 { 7375 PetscErrorCode ierr; 7376 7377 PetscFunctionBegin; 7378 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7379 PetscValidType(mat,1); 7380 PetscValidIntPointer(n,4); 7381 if (ia) PetscValidIntPointer(ia,5); 7382 if (ja) PetscValidIntPointer(ja,6); 7383 PetscValidIntPointer(done,7); 7384 MatCheckPreallocated(mat,1); 7385 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7386 else { 7387 *done = PETSC_TRUE; 7388 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7389 } 7390 PetscFunctionReturn(0); 7391 } 7392 7393 /*@C 7394 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7395 MatGetRowIJ(). 7396 7397 Collective on Mat 7398 7399 Input Parameters: 7400 + mat - the matrix 7401 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7402 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7403 symmetrized 7404 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7405 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7406 always used. 7407 . n - size of (possibly compressed) matrix 7408 . ia - the row pointers 7409 - ja - the column indices 7410 7411 Output Parameters: 7412 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7413 7414 Note: 7415 This routine zeros out n, ia, and ja. This is to prevent accidental 7416 us of the array after it has been restored. If you pass NULL, it will 7417 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7418 7419 Level: developer 7420 7421 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7422 @*/ 7423 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7424 { 7425 PetscErrorCode ierr; 7426 7427 PetscFunctionBegin; 7428 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7429 PetscValidType(mat,1); 7430 if (ia) PetscValidIntPointer(ia,6); 7431 if (ja) PetscValidIntPointer(ja,7); 7432 PetscValidIntPointer(done,8); 7433 MatCheckPreallocated(mat,1); 7434 7435 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7436 else { 7437 *done = PETSC_TRUE; 7438 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7439 if (n) *n = 0; 7440 if (ia) *ia = NULL; 7441 if (ja) *ja = NULL; 7442 } 7443 PetscFunctionReturn(0); 7444 } 7445 7446 /*@C 7447 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7448 MatGetColumnIJ(). 7449 7450 Collective on Mat 7451 7452 Input Parameters: 7453 + mat - the matrix 7454 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7455 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7456 symmetrized 7457 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7458 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7459 always used. 7460 7461 Output Parameters: 7462 + n - size of (possibly compressed) matrix 7463 . ia - the column pointers 7464 . ja - the row indices 7465 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7466 7467 Level: developer 7468 7469 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7470 @*/ 7471 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7472 { 7473 PetscErrorCode ierr; 7474 7475 PetscFunctionBegin; 7476 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7477 PetscValidType(mat,1); 7478 if (ia) PetscValidIntPointer(ia,5); 7479 if (ja) PetscValidIntPointer(ja,6); 7480 PetscValidIntPointer(done,7); 7481 MatCheckPreallocated(mat,1); 7482 7483 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7484 else { 7485 *done = PETSC_TRUE; 7486 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7487 if (n) *n = 0; 7488 if (ia) *ia = NULL; 7489 if (ja) *ja = NULL; 7490 } 7491 PetscFunctionReturn(0); 7492 } 7493 7494 /*@C 7495 MatColoringPatch -Used inside matrix coloring routines that 7496 use MatGetRowIJ() and/or MatGetColumnIJ(). 7497 7498 Collective on Mat 7499 7500 Input Parameters: 7501 + mat - the matrix 7502 . ncolors - max color value 7503 . n - number of entries in colorarray 7504 - colorarray - array indicating color for each column 7505 7506 Output Parameters: 7507 . iscoloring - coloring generated using colorarray information 7508 7509 Level: developer 7510 7511 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7512 7513 @*/ 7514 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7515 { 7516 PetscErrorCode ierr; 7517 7518 PetscFunctionBegin; 7519 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7520 PetscValidType(mat,1); 7521 PetscValidIntPointer(colorarray,4); 7522 PetscValidPointer(iscoloring,5); 7523 MatCheckPreallocated(mat,1); 7524 7525 if (!mat->ops->coloringpatch) { 7526 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7527 } else { 7528 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7529 } 7530 PetscFunctionReturn(0); 7531 } 7532 7533 7534 /*@ 7535 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7536 7537 Logically Collective on Mat 7538 7539 Input Parameter: 7540 . mat - the factored matrix to be reset 7541 7542 Notes: 7543 This routine should be used only with factored matrices formed by in-place 7544 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7545 format). This option can save memory, for example, when solving nonlinear 7546 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7547 ILU(0) preconditioner. 7548 7549 Note that one can specify in-place ILU(0) factorization by calling 7550 .vb 7551 PCType(pc,PCILU); 7552 PCFactorSeUseInPlace(pc); 7553 .ve 7554 or by using the options -pc_type ilu -pc_factor_in_place 7555 7556 In-place factorization ILU(0) can also be used as a local 7557 solver for the blocks within the block Jacobi or additive Schwarz 7558 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7559 for details on setting local solver options. 7560 7561 Most users should employ the simplified KSP interface for linear solvers 7562 instead of working directly with matrix algebra routines such as this. 7563 See, e.g., KSPCreate(). 7564 7565 Level: developer 7566 7567 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7568 7569 @*/ 7570 PetscErrorCode MatSetUnfactored(Mat mat) 7571 { 7572 PetscErrorCode ierr; 7573 7574 PetscFunctionBegin; 7575 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7576 PetscValidType(mat,1); 7577 MatCheckPreallocated(mat,1); 7578 mat->factortype = MAT_FACTOR_NONE; 7579 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7580 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7581 PetscFunctionReturn(0); 7582 } 7583 7584 /*MC 7585 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7586 7587 Synopsis: 7588 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7589 7590 Not collective 7591 7592 Input Parameter: 7593 . x - matrix 7594 7595 Output Parameters: 7596 + xx_v - the Fortran90 pointer to the array 7597 - ierr - error code 7598 7599 Example of Usage: 7600 .vb 7601 PetscScalar, pointer xx_v(:,:) 7602 .... 7603 call MatDenseGetArrayF90(x,xx_v,ierr) 7604 a = xx_v(3) 7605 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7606 .ve 7607 7608 Level: advanced 7609 7610 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7611 7612 M*/ 7613 7614 /*MC 7615 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7616 accessed with MatDenseGetArrayF90(). 7617 7618 Synopsis: 7619 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7620 7621 Not collective 7622 7623 Input Parameters: 7624 + x - matrix 7625 - xx_v - the Fortran90 pointer to the array 7626 7627 Output Parameter: 7628 . ierr - error code 7629 7630 Example of Usage: 7631 .vb 7632 PetscScalar, pointer xx_v(:,:) 7633 .... 7634 call MatDenseGetArrayF90(x,xx_v,ierr) 7635 a = xx_v(3) 7636 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7637 .ve 7638 7639 Level: advanced 7640 7641 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7642 7643 M*/ 7644 7645 7646 /*MC 7647 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7648 7649 Synopsis: 7650 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7651 7652 Not collective 7653 7654 Input Parameter: 7655 . x - matrix 7656 7657 Output Parameters: 7658 + xx_v - the Fortran90 pointer to the array 7659 - ierr - error code 7660 7661 Example of Usage: 7662 .vb 7663 PetscScalar, pointer xx_v(:) 7664 .... 7665 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7666 a = xx_v(3) 7667 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7668 .ve 7669 7670 Level: advanced 7671 7672 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7673 7674 M*/ 7675 7676 /*MC 7677 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7678 accessed with MatSeqAIJGetArrayF90(). 7679 7680 Synopsis: 7681 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7682 7683 Not collective 7684 7685 Input Parameters: 7686 + x - matrix 7687 - xx_v - the Fortran90 pointer to the array 7688 7689 Output Parameter: 7690 . ierr - error code 7691 7692 Example of Usage: 7693 .vb 7694 PetscScalar, pointer xx_v(:) 7695 .... 7696 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7697 a = xx_v(3) 7698 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7699 .ve 7700 7701 Level: advanced 7702 7703 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7704 7705 M*/ 7706 7707 7708 /*@ 7709 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7710 as the original matrix. 7711 7712 Collective on Mat 7713 7714 Input Parameters: 7715 + mat - the original matrix 7716 . isrow - parallel IS containing the rows this processor should obtain 7717 . 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. 7718 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7719 7720 Output Parameter: 7721 . newmat - the new submatrix, of the same type as the old 7722 7723 Level: advanced 7724 7725 Notes: 7726 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7727 7728 Some matrix types place restrictions on the row and column indices, such 7729 as that they be sorted or that they be equal to each other. 7730 7731 The index sets may not have duplicate entries. 7732 7733 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7734 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 7735 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7736 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7737 you are finished using it. 7738 7739 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7740 the input matrix. 7741 7742 If iscol is NULL then all columns are obtained (not supported in Fortran). 7743 7744 Example usage: 7745 Consider the following 8x8 matrix with 34 non-zero values, that is 7746 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7747 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7748 as follows: 7749 7750 .vb 7751 1 2 0 | 0 3 0 | 0 4 7752 Proc0 0 5 6 | 7 0 0 | 8 0 7753 9 0 10 | 11 0 0 | 12 0 7754 ------------------------------------- 7755 13 0 14 | 15 16 17 | 0 0 7756 Proc1 0 18 0 | 19 20 21 | 0 0 7757 0 0 0 | 22 23 0 | 24 0 7758 ------------------------------------- 7759 Proc2 25 26 27 | 0 0 28 | 29 0 7760 30 0 0 | 31 32 33 | 0 34 7761 .ve 7762 7763 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7764 7765 .vb 7766 2 0 | 0 3 0 | 0 7767 Proc0 5 6 | 7 0 0 | 8 7768 ------------------------------- 7769 Proc1 18 0 | 19 20 21 | 0 7770 ------------------------------- 7771 Proc2 26 27 | 0 0 28 | 29 7772 0 0 | 31 32 33 | 0 7773 .ve 7774 7775 7776 .seealso: MatCreateSubMatrices(), MatCreateSubMatricesMPI(), MatCreateSubMatrixVirtual(), MatSubMatrixVirtualUpdate() 7777 @*/ 7778 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7779 { 7780 PetscErrorCode ierr; 7781 PetscMPIInt size; 7782 Mat *local; 7783 IS iscoltmp; 7784 7785 PetscFunctionBegin; 7786 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7787 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7788 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7789 PetscValidPointer(newmat,5); 7790 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7791 PetscValidType(mat,1); 7792 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7793 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 7794 7795 MatCheckPreallocated(mat,1); 7796 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 7797 7798 if (!iscol || isrow == iscol) { 7799 PetscBool stride; 7800 PetscMPIInt grabentirematrix = 0,grab; 7801 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 7802 if (stride) { 7803 PetscInt first,step,n,rstart,rend; 7804 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 7805 if (step == 1) { 7806 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 7807 if (rstart == first) { 7808 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 7809 if (n == rend-rstart) { 7810 grabentirematrix = 1; 7811 } 7812 } 7813 } 7814 } 7815 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 7816 if (grab) { 7817 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 7818 if (cll == MAT_INITIAL_MATRIX) { 7819 *newmat = mat; 7820 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 7821 } 7822 PetscFunctionReturn(0); 7823 } 7824 } 7825 7826 if (!iscol) { 7827 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 7828 } else { 7829 iscoltmp = iscol; 7830 } 7831 7832 /* if original matrix is on just one processor then use submatrix generated */ 7833 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 7834 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 7835 goto setproperties; 7836 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 7837 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 7838 *newmat = *local; 7839 ierr = PetscFree(local);CHKERRQ(ierr); 7840 goto setproperties; 7841 } else if (!mat->ops->createsubmatrix) { 7842 /* Create a new matrix type that implements the operation using the full matrix */ 7843 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7844 switch (cll) { 7845 case MAT_INITIAL_MATRIX: 7846 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 7847 break; 7848 case MAT_REUSE_MATRIX: 7849 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 7850 break; 7851 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 7852 } 7853 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7854 goto setproperties; 7855 } 7856 7857 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7858 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7859 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 7860 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7861 7862 /* Propagate symmetry information for diagonal blocks */ 7863 setproperties: 7864 if (isrow == iscoltmp) { 7865 if (mat->symmetric_set && mat->symmetric) { 7866 ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 7867 } 7868 if (mat->structurally_symmetric_set && mat->structurally_symmetric) { 7869 ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 7870 } 7871 if (mat->hermitian_set && mat->hermitian) { 7872 ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 7873 } 7874 if (mat->spd_set && mat->spd) { 7875 ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 7876 } 7877 } 7878 7879 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7880 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 7881 PetscFunctionReturn(0); 7882 } 7883 7884 /*@ 7885 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 7886 used during the assembly process to store values that belong to 7887 other processors. 7888 7889 Not Collective 7890 7891 Input Parameters: 7892 + mat - the matrix 7893 . size - the initial size of the stash. 7894 - bsize - the initial size of the block-stash(if used). 7895 7896 Options Database Keys: 7897 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 7898 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 7899 7900 Level: intermediate 7901 7902 Notes: 7903 The block-stash is used for values set with MatSetValuesBlocked() while 7904 the stash is used for values set with MatSetValues() 7905 7906 Run with the option -info and look for output of the form 7907 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 7908 to determine the appropriate value, MM, to use for size and 7909 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 7910 to determine the value, BMM to use for bsize 7911 7912 7913 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 7914 7915 @*/ 7916 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 7917 { 7918 PetscErrorCode ierr; 7919 7920 PetscFunctionBegin; 7921 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7922 PetscValidType(mat,1); 7923 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 7924 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 7925 PetscFunctionReturn(0); 7926 } 7927 7928 /*@ 7929 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 7930 the matrix 7931 7932 Neighbor-wise Collective on Mat 7933 7934 Input Parameters: 7935 + mat - the matrix 7936 . x,y - the vectors 7937 - w - where the result is stored 7938 7939 Level: intermediate 7940 7941 Notes: 7942 w may be the same vector as y. 7943 7944 This allows one to use either the restriction or interpolation (its transpose) 7945 matrix to do the interpolation 7946 7947 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 7948 7949 @*/ 7950 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 7951 { 7952 PetscErrorCode ierr; 7953 PetscInt M,N,Ny; 7954 7955 PetscFunctionBegin; 7956 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7957 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7958 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 7959 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 7960 PetscValidType(A,1); 7961 MatCheckPreallocated(A,1); 7962 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 7963 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 7964 if (M == Ny) { 7965 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 7966 } else { 7967 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 7968 } 7969 PetscFunctionReturn(0); 7970 } 7971 7972 /*@ 7973 MatInterpolate - y = A*x or A'*x depending on the shape of 7974 the matrix 7975 7976 Neighbor-wise Collective on Mat 7977 7978 Input Parameters: 7979 + mat - the matrix 7980 - x,y - the vectors 7981 7982 Level: intermediate 7983 7984 Notes: 7985 This allows one to use either the restriction or interpolation (its transpose) 7986 matrix to do the interpolation 7987 7988 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 7989 7990 @*/ 7991 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 7992 { 7993 PetscErrorCode ierr; 7994 PetscInt M,N,Ny; 7995 7996 PetscFunctionBegin; 7997 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7998 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7999 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8000 PetscValidType(A,1); 8001 MatCheckPreallocated(A,1); 8002 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8003 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8004 if (M == Ny) { 8005 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8006 } else { 8007 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8008 } 8009 PetscFunctionReturn(0); 8010 } 8011 8012 /*@ 8013 MatRestrict - y = A*x or A'*x 8014 8015 Neighbor-wise Collective on Mat 8016 8017 Input Parameters: 8018 + mat - the matrix 8019 - x,y - the vectors 8020 8021 Level: intermediate 8022 8023 Notes: 8024 This allows one to use either the restriction or interpolation (its transpose) 8025 matrix to do the restriction 8026 8027 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8028 8029 @*/ 8030 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8031 { 8032 PetscErrorCode ierr; 8033 PetscInt M,N,Ny; 8034 8035 PetscFunctionBegin; 8036 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8037 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8038 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8039 PetscValidType(A,1); 8040 MatCheckPreallocated(A,1); 8041 8042 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8043 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8044 if (M == Ny) { 8045 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8046 } else { 8047 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8048 } 8049 PetscFunctionReturn(0); 8050 } 8051 8052 /*@ 8053 MatGetNullSpace - retrieves the null space of a matrix. 8054 8055 Logically Collective on Mat 8056 8057 Input Parameters: 8058 + mat - the matrix 8059 - nullsp - the null space object 8060 8061 Level: developer 8062 8063 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8064 @*/ 8065 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8066 { 8067 PetscFunctionBegin; 8068 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8069 PetscValidPointer(nullsp,2); 8070 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8071 PetscFunctionReturn(0); 8072 } 8073 8074 /*@ 8075 MatSetNullSpace - attaches a null space to a matrix. 8076 8077 Logically Collective on Mat 8078 8079 Input Parameters: 8080 + mat - the matrix 8081 - nullsp - the null space object 8082 8083 Level: advanced 8084 8085 Notes: 8086 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8087 8088 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8089 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8090 8091 You can remove the null space by calling this routine with an nullsp of NULL 8092 8093 8094 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8095 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). 8096 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 8097 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 8098 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). 8099 8100 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8101 8102 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 8103 routine also automatically calls MatSetTransposeNullSpace(). 8104 8105 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8106 @*/ 8107 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8108 { 8109 PetscErrorCode ierr; 8110 8111 PetscFunctionBegin; 8112 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8113 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8114 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8115 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8116 mat->nullsp = nullsp; 8117 if (mat->symmetric_set && mat->symmetric) { 8118 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8119 } 8120 PetscFunctionReturn(0); 8121 } 8122 8123 /*@ 8124 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8125 8126 Logically Collective on Mat 8127 8128 Input Parameters: 8129 + mat - the matrix 8130 - nullsp - the null space object 8131 8132 Level: developer 8133 8134 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8135 @*/ 8136 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8137 { 8138 PetscFunctionBegin; 8139 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8140 PetscValidType(mat,1); 8141 PetscValidPointer(nullsp,2); 8142 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8143 PetscFunctionReturn(0); 8144 } 8145 8146 /*@ 8147 MatSetTransposeNullSpace - attaches a null space to a matrix. 8148 8149 Logically Collective on Mat 8150 8151 Input Parameters: 8152 + mat - the matrix 8153 - nullsp - the null space object 8154 8155 Level: advanced 8156 8157 Notes: 8158 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) this allows the linear system to be solved in a least squares sense. 8159 You must also call MatSetNullSpace() 8160 8161 8162 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8163 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). 8164 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 8165 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 8166 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). 8167 8168 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8169 8170 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8171 @*/ 8172 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8173 { 8174 PetscErrorCode ierr; 8175 8176 PetscFunctionBegin; 8177 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8178 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8179 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8180 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8181 mat->transnullsp = nullsp; 8182 PetscFunctionReturn(0); 8183 } 8184 8185 /*@ 8186 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8187 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8188 8189 Logically Collective on Mat 8190 8191 Input Parameters: 8192 + mat - the matrix 8193 - nullsp - the null space object 8194 8195 Level: advanced 8196 8197 Notes: 8198 Overwrites any previous near null space that may have been attached 8199 8200 You can remove the null space by calling this routine with an nullsp of NULL 8201 8202 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8203 @*/ 8204 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8205 { 8206 PetscErrorCode ierr; 8207 8208 PetscFunctionBegin; 8209 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8210 PetscValidType(mat,1); 8211 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8212 MatCheckPreallocated(mat,1); 8213 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8214 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8215 mat->nearnullsp = nullsp; 8216 PetscFunctionReturn(0); 8217 } 8218 8219 /*@ 8220 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8221 8222 Not Collective 8223 8224 Input Parameters: 8225 . mat - the matrix 8226 8227 Output Parameters: 8228 . nullsp - the null space object, NULL if not set 8229 8230 Level: developer 8231 8232 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8233 @*/ 8234 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8235 { 8236 PetscFunctionBegin; 8237 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8238 PetscValidType(mat,1); 8239 PetscValidPointer(nullsp,2); 8240 MatCheckPreallocated(mat,1); 8241 *nullsp = mat->nearnullsp; 8242 PetscFunctionReturn(0); 8243 } 8244 8245 /*@C 8246 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8247 8248 Collective on Mat 8249 8250 Input Parameters: 8251 + mat - the matrix 8252 . row - row/column permutation 8253 . fill - expected fill factor >= 1.0 8254 - level - level of fill, for ICC(k) 8255 8256 Notes: 8257 Probably really in-place only when level of fill is zero, otherwise allocates 8258 new space to store factored matrix and deletes previous memory. 8259 8260 Most users should employ the simplified KSP interface for linear solvers 8261 instead of working directly with matrix algebra routines such as this. 8262 See, e.g., KSPCreate(). 8263 8264 Level: developer 8265 8266 8267 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8268 8269 Developer Note: fortran interface is not autogenerated as the f90 8270 interface defintion cannot be generated correctly [due to MatFactorInfo] 8271 8272 @*/ 8273 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8274 { 8275 PetscErrorCode ierr; 8276 8277 PetscFunctionBegin; 8278 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8279 PetscValidType(mat,1); 8280 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8281 PetscValidPointer(info,3); 8282 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8283 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8284 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8285 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8286 MatCheckPreallocated(mat,1); 8287 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8288 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8289 PetscFunctionReturn(0); 8290 } 8291 8292 /*@ 8293 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8294 ghosted ones. 8295 8296 Not Collective 8297 8298 Input Parameters: 8299 + mat - the matrix 8300 - diag = the diagonal values, including ghost ones 8301 8302 Level: developer 8303 8304 Notes: 8305 Works only for MPIAIJ and MPIBAIJ matrices 8306 8307 .seealso: MatDiagonalScale() 8308 @*/ 8309 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8310 { 8311 PetscErrorCode ierr; 8312 PetscMPIInt size; 8313 8314 PetscFunctionBegin; 8315 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8316 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8317 PetscValidType(mat,1); 8318 8319 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8320 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8321 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8322 if (size == 1) { 8323 PetscInt n,m; 8324 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8325 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8326 if (m == n) { 8327 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8328 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8329 } else { 8330 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8331 } 8332 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8333 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8334 PetscFunctionReturn(0); 8335 } 8336 8337 /*@ 8338 MatGetInertia - Gets the inertia from a factored matrix 8339 8340 Collective on Mat 8341 8342 Input Parameter: 8343 . mat - the matrix 8344 8345 Output Parameters: 8346 + nneg - number of negative eigenvalues 8347 . nzero - number of zero eigenvalues 8348 - npos - number of positive eigenvalues 8349 8350 Level: advanced 8351 8352 Notes: 8353 Matrix must have been factored by MatCholeskyFactor() 8354 8355 8356 @*/ 8357 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8358 { 8359 PetscErrorCode ierr; 8360 8361 PetscFunctionBegin; 8362 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8363 PetscValidType(mat,1); 8364 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8365 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8366 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8367 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8368 PetscFunctionReturn(0); 8369 } 8370 8371 /* ----------------------------------------------------------------*/ 8372 /*@C 8373 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8374 8375 Neighbor-wise Collective on Mats 8376 8377 Input Parameters: 8378 + mat - the factored matrix 8379 - b - the right-hand-side vectors 8380 8381 Output Parameter: 8382 . x - the result vectors 8383 8384 Notes: 8385 The vectors b and x cannot be the same. I.e., one cannot 8386 call MatSolves(A,x,x). 8387 8388 Notes: 8389 Most users should employ the simplified KSP interface for linear solvers 8390 instead of working directly with matrix algebra routines such as this. 8391 See, e.g., KSPCreate(). 8392 8393 Level: developer 8394 8395 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8396 @*/ 8397 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8398 { 8399 PetscErrorCode ierr; 8400 8401 PetscFunctionBegin; 8402 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8403 PetscValidType(mat,1); 8404 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8405 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8406 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8407 8408 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8409 MatCheckPreallocated(mat,1); 8410 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8411 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8412 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8413 PetscFunctionReturn(0); 8414 } 8415 8416 /*@ 8417 MatIsSymmetric - Test whether a matrix is symmetric 8418 8419 Collective on Mat 8420 8421 Input Parameter: 8422 + A - the matrix to test 8423 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8424 8425 Output Parameters: 8426 . flg - the result 8427 8428 Notes: 8429 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8430 8431 Level: intermediate 8432 8433 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8434 @*/ 8435 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8436 { 8437 PetscErrorCode ierr; 8438 8439 PetscFunctionBegin; 8440 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8441 PetscValidBoolPointer(flg,2); 8442 8443 if (!A->symmetric_set) { 8444 if (!A->ops->issymmetric) { 8445 MatType mattype; 8446 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8447 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8448 } 8449 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8450 if (!tol) { 8451 A->symmetric_set = PETSC_TRUE; 8452 A->symmetric = *flg; 8453 if (A->symmetric) { 8454 A->structurally_symmetric_set = PETSC_TRUE; 8455 A->structurally_symmetric = PETSC_TRUE; 8456 } 8457 } 8458 } else if (A->symmetric) { 8459 *flg = PETSC_TRUE; 8460 } else if (!tol) { 8461 *flg = PETSC_FALSE; 8462 } else { 8463 if (!A->ops->issymmetric) { 8464 MatType mattype; 8465 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8466 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8467 } 8468 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8469 } 8470 PetscFunctionReturn(0); 8471 } 8472 8473 /*@ 8474 MatIsHermitian - Test whether a matrix is Hermitian 8475 8476 Collective on Mat 8477 8478 Input Parameter: 8479 + A - the matrix to test 8480 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8481 8482 Output Parameters: 8483 . flg - the result 8484 8485 Level: intermediate 8486 8487 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8488 MatIsSymmetricKnown(), MatIsSymmetric() 8489 @*/ 8490 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8491 { 8492 PetscErrorCode ierr; 8493 8494 PetscFunctionBegin; 8495 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8496 PetscValidBoolPointer(flg,2); 8497 8498 if (!A->hermitian_set) { 8499 if (!A->ops->ishermitian) { 8500 MatType mattype; 8501 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8502 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8503 } 8504 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8505 if (!tol) { 8506 A->hermitian_set = PETSC_TRUE; 8507 A->hermitian = *flg; 8508 if (A->hermitian) { 8509 A->structurally_symmetric_set = PETSC_TRUE; 8510 A->structurally_symmetric = PETSC_TRUE; 8511 } 8512 } 8513 } else if (A->hermitian) { 8514 *flg = PETSC_TRUE; 8515 } else if (!tol) { 8516 *flg = PETSC_FALSE; 8517 } else { 8518 if (!A->ops->ishermitian) { 8519 MatType mattype; 8520 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8521 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8522 } 8523 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8524 } 8525 PetscFunctionReturn(0); 8526 } 8527 8528 /*@ 8529 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8530 8531 Not Collective 8532 8533 Input Parameter: 8534 . A - the matrix to check 8535 8536 Output Parameters: 8537 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8538 - flg - the result 8539 8540 Level: advanced 8541 8542 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8543 if you want it explicitly checked 8544 8545 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8546 @*/ 8547 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8548 { 8549 PetscFunctionBegin; 8550 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8551 PetscValidPointer(set,2); 8552 PetscValidBoolPointer(flg,3); 8553 if (A->symmetric_set) { 8554 *set = PETSC_TRUE; 8555 *flg = A->symmetric; 8556 } else { 8557 *set = PETSC_FALSE; 8558 } 8559 PetscFunctionReturn(0); 8560 } 8561 8562 /*@ 8563 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8564 8565 Not Collective 8566 8567 Input Parameter: 8568 . A - the matrix to check 8569 8570 Output Parameters: 8571 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8572 - flg - the result 8573 8574 Level: advanced 8575 8576 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8577 if you want it explicitly checked 8578 8579 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8580 @*/ 8581 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8582 { 8583 PetscFunctionBegin; 8584 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8585 PetscValidPointer(set,2); 8586 PetscValidBoolPointer(flg,3); 8587 if (A->hermitian_set) { 8588 *set = PETSC_TRUE; 8589 *flg = A->hermitian; 8590 } else { 8591 *set = PETSC_FALSE; 8592 } 8593 PetscFunctionReturn(0); 8594 } 8595 8596 /*@ 8597 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8598 8599 Collective on Mat 8600 8601 Input Parameter: 8602 . A - the matrix to test 8603 8604 Output Parameters: 8605 . flg - the result 8606 8607 Level: intermediate 8608 8609 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8610 @*/ 8611 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8612 { 8613 PetscErrorCode ierr; 8614 8615 PetscFunctionBegin; 8616 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8617 PetscValidBoolPointer(flg,2); 8618 if (!A->structurally_symmetric_set) { 8619 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8620 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8621 8622 A->structurally_symmetric_set = PETSC_TRUE; 8623 } 8624 *flg = A->structurally_symmetric; 8625 PetscFunctionReturn(0); 8626 } 8627 8628 /*@ 8629 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8630 to be communicated to other processors during the MatAssemblyBegin/End() process 8631 8632 Not collective 8633 8634 Input Parameter: 8635 . vec - the vector 8636 8637 Output Parameters: 8638 + nstash - the size of the stash 8639 . reallocs - the number of additional mallocs incurred. 8640 . bnstash - the size of the block stash 8641 - breallocs - the number of additional mallocs incurred.in the block stash 8642 8643 Level: advanced 8644 8645 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8646 8647 @*/ 8648 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8649 { 8650 PetscErrorCode ierr; 8651 8652 PetscFunctionBegin; 8653 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8654 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8655 PetscFunctionReturn(0); 8656 } 8657 8658 /*@C 8659 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8660 parallel layout 8661 8662 Collective on Mat 8663 8664 Input Parameter: 8665 . mat - the matrix 8666 8667 Output Parameter: 8668 + right - (optional) vector that the matrix can be multiplied against 8669 - left - (optional) vector that the matrix vector product can be stored in 8670 8671 Notes: 8672 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(). 8673 8674 Notes: 8675 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8676 8677 Level: advanced 8678 8679 .seealso: MatCreate(), VecDestroy() 8680 @*/ 8681 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8682 { 8683 PetscErrorCode ierr; 8684 8685 PetscFunctionBegin; 8686 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8687 PetscValidType(mat,1); 8688 if (mat->ops->getvecs) { 8689 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8690 } else { 8691 PetscInt rbs,cbs; 8692 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8693 if (right) { 8694 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8695 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8696 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8697 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8698 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 8699 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8700 } 8701 if (left) { 8702 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8703 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8704 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8705 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8706 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 8707 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8708 } 8709 } 8710 PetscFunctionReturn(0); 8711 } 8712 8713 /*@C 8714 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8715 with default values. 8716 8717 Not Collective 8718 8719 Input Parameters: 8720 . info - the MatFactorInfo data structure 8721 8722 8723 Notes: 8724 The solvers are generally used through the KSP and PC objects, for example 8725 PCLU, PCILU, PCCHOLESKY, PCICC 8726 8727 Level: developer 8728 8729 .seealso: MatFactorInfo 8730 8731 Developer Note: fortran interface is not autogenerated as the f90 8732 interface defintion cannot be generated correctly [due to MatFactorInfo] 8733 8734 @*/ 8735 8736 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8737 { 8738 PetscErrorCode ierr; 8739 8740 PetscFunctionBegin; 8741 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8742 PetscFunctionReturn(0); 8743 } 8744 8745 /*@ 8746 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 8747 8748 Collective on Mat 8749 8750 Input Parameters: 8751 + mat - the factored matrix 8752 - is - the index set defining the Schur indices (0-based) 8753 8754 Notes: 8755 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 8756 8757 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 8758 8759 Level: developer 8760 8761 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 8762 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 8763 8764 @*/ 8765 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 8766 { 8767 PetscErrorCode ierr,(*f)(Mat,IS); 8768 8769 PetscFunctionBegin; 8770 PetscValidType(mat,1); 8771 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8772 PetscValidType(is,2); 8773 PetscValidHeaderSpecific(is,IS_CLASSID,2); 8774 PetscCheckSameComm(mat,1,is,2); 8775 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 8776 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 8777 if (!f) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverType does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO"); 8778 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 8779 ierr = (*f)(mat,is);CHKERRQ(ierr); 8780 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 8781 PetscFunctionReturn(0); 8782 } 8783 8784 /*@ 8785 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 8786 8787 Logically Collective on Mat 8788 8789 Input Parameters: 8790 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 8791 . S - location where to return the Schur complement, can be NULL 8792 - status - the status of the Schur complement matrix, can be NULL 8793 8794 Notes: 8795 You must call MatFactorSetSchurIS() before calling this routine. 8796 8797 The routine provides a copy of the Schur matrix stored within the solver data structures. 8798 The caller must destroy the object when it is no longer needed. 8799 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 8800 8801 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) 8802 8803 Developer Notes: 8804 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 8805 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 8806 8807 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 8808 8809 Level: advanced 8810 8811 References: 8812 8813 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 8814 @*/ 8815 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 8816 { 8817 PetscErrorCode ierr; 8818 8819 PetscFunctionBegin; 8820 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8821 if (S) PetscValidPointer(S,2); 8822 if (status) PetscValidPointer(status,3); 8823 if (S) { 8824 PetscErrorCode (*f)(Mat,Mat*); 8825 8826 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 8827 if (f) { 8828 ierr = (*f)(F,S);CHKERRQ(ierr); 8829 } else { 8830 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 8831 } 8832 } 8833 if (status) *status = F->schur_status; 8834 PetscFunctionReturn(0); 8835 } 8836 8837 /*@ 8838 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 8839 8840 Logically Collective on Mat 8841 8842 Input Parameters: 8843 + F - the factored matrix obtained by calling MatGetFactor() 8844 . *S - location where to return the Schur complement, can be NULL 8845 - status - the status of the Schur complement matrix, can be NULL 8846 8847 Notes: 8848 You must call MatFactorSetSchurIS() before calling this routine. 8849 8850 Schur complement mode is currently implemented for sequential matrices. 8851 The routine returns a the Schur Complement stored within the data strutures of the solver. 8852 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 8853 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 8854 8855 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 8856 8857 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 8858 8859 Level: advanced 8860 8861 References: 8862 8863 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 8864 @*/ 8865 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 8866 { 8867 PetscFunctionBegin; 8868 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8869 if (S) PetscValidPointer(S,2); 8870 if (status) PetscValidPointer(status,3); 8871 if (S) *S = F->schur; 8872 if (status) *status = F->schur_status; 8873 PetscFunctionReturn(0); 8874 } 8875 8876 /*@ 8877 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 8878 8879 Logically Collective on Mat 8880 8881 Input Parameters: 8882 + F - the factored matrix obtained by calling MatGetFactor() 8883 . *S - location where the Schur complement is stored 8884 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 8885 8886 Notes: 8887 8888 Level: advanced 8889 8890 References: 8891 8892 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 8893 @*/ 8894 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 8895 { 8896 PetscErrorCode ierr; 8897 8898 PetscFunctionBegin; 8899 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8900 if (S) { 8901 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 8902 *S = NULL; 8903 } 8904 F->schur_status = status; 8905 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 8906 PetscFunctionReturn(0); 8907 } 8908 8909 /*@ 8910 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 8911 8912 Logically Collective on Mat 8913 8914 Input Parameters: 8915 + F - the factored matrix obtained by calling MatGetFactor() 8916 . rhs - location where the right hand side of the Schur complement system is stored 8917 - sol - location where the solution of the Schur complement system has to be returned 8918 8919 Notes: 8920 The sizes of the vectors should match the size of the Schur complement 8921 8922 Must be called after MatFactorSetSchurIS() 8923 8924 Level: advanced 8925 8926 References: 8927 8928 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 8929 @*/ 8930 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 8931 { 8932 PetscErrorCode ierr; 8933 8934 PetscFunctionBegin; 8935 PetscValidType(F,1); 8936 PetscValidType(rhs,2); 8937 PetscValidType(sol,3); 8938 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8939 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 8940 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 8941 PetscCheckSameComm(F,1,rhs,2); 8942 PetscCheckSameComm(F,1,sol,3); 8943 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 8944 switch (F->schur_status) { 8945 case MAT_FACTOR_SCHUR_FACTORED: 8946 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 8947 break; 8948 case MAT_FACTOR_SCHUR_INVERTED: 8949 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 8950 break; 8951 default: 8952 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 8953 break; 8954 } 8955 PetscFunctionReturn(0); 8956 } 8957 8958 /*@ 8959 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 8960 8961 Logically Collective on Mat 8962 8963 Input Parameters: 8964 + F - the factored matrix obtained by calling MatGetFactor() 8965 . rhs - location where the right hand side of the Schur complement system is stored 8966 - sol - location where the solution of the Schur complement system has to be returned 8967 8968 Notes: 8969 The sizes of the vectors should match the size of the Schur complement 8970 8971 Must be called after MatFactorSetSchurIS() 8972 8973 Level: advanced 8974 8975 References: 8976 8977 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 8978 @*/ 8979 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 8980 { 8981 PetscErrorCode ierr; 8982 8983 PetscFunctionBegin; 8984 PetscValidType(F,1); 8985 PetscValidType(rhs,2); 8986 PetscValidType(sol,3); 8987 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8988 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 8989 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 8990 PetscCheckSameComm(F,1,rhs,2); 8991 PetscCheckSameComm(F,1,sol,3); 8992 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 8993 switch (F->schur_status) { 8994 case MAT_FACTOR_SCHUR_FACTORED: 8995 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 8996 break; 8997 case MAT_FACTOR_SCHUR_INVERTED: 8998 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 8999 break; 9000 default: 9001 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9002 break; 9003 } 9004 PetscFunctionReturn(0); 9005 } 9006 9007 /*@ 9008 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9009 9010 Logically Collective on Mat 9011 9012 Input Parameters: 9013 . F - the factored matrix obtained by calling MatGetFactor() 9014 9015 Notes: 9016 Must be called after MatFactorSetSchurIS(). 9017 9018 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9019 9020 Level: advanced 9021 9022 References: 9023 9024 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9025 @*/ 9026 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9027 { 9028 PetscErrorCode ierr; 9029 9030 PetscFunctionBegin; 9031 PetscValidType(F,1); 9032 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9033 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9034 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9035 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9036 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9037 PetscFunctionReturn(0); 9038 } 9039 9040 /*@ 9041 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9042 9043 Logically Collective on Mat 9044 9045 Input Parameters: 9046 . F - the factored matrix obtained by calling MatGetFactor() 9047 9048 Notes: 9049 Must be called after MatFactorSetSchurIS(). 9050 9051 Level: advanced 9052 9053 References: 9054 9055 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9056 @*/ 9057 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9058 { 9059 PetscErrorCode ierr; 9060 9061 PetscFunctionBegin; 9062 PetscValidType(F,1); 9063 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9064 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9065 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9066 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9067 PetscFunctionReturn(0); 9068 } 9069 9070 PetscErrorCode MatPtAP_Basic(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9071 { 9072 Mat AP; 9073 PetscErrorCode ierr; 9074 9075 PetscFunctionBegin; 9076 ierr = PetscInfo2(A,"Mat types %s and %s using basic PtAP\n",((PetscObject)A)->type_name,((PetscObject)P)->type_name);CHKERRQ(ierr); 9077 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AP);CHKERRQ(ierr); 9078 ierr = MatTransposeMatMult(P,AP,scall,fill,C);CHKERRQ(ierr); 9079 ierr = MatDestroy(&AP);CHKERRQ(ierr); 9080 PetscFunctionReturn(0); 9081 } 9082 9083 /*@ 9084 MatPtAP - Creates the matrix product C = P^T * A * P 9085 9086 Neighbor-wise Collective on Mat 9087 9088 Input Parameters: 9089 + A - the matrix 9090 . P - the projection matrix 9091 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9092 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9093 if the result is a dense matrix this is irrelevent 9094 9095 Output Parameters: 9096 . C - the product matrix 9097 9098 Notes: 9099 C will be created and must be destroyed by the user with MatDestroy(). 9100 9101 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9102 9103 Level: intermediate 9104 9105 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9106 @*/ 9107 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9108 { 9109 PetscErrorCode ierr; 9110 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9111 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9112 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9113 PetscBool sametype; 9114 9115 PetscFunctionBegin; 9116 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9117 PetscValidType(A,1); 9118 MatCheckPreallocated(A,1); 9119 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9120 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9121 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9122 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9123 PetscValidType(P,2); 9124 MatCheckPreallocated(P,2); 9125 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9126 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9127 9128 if (A->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix A must be square, %D != %D",A->rmap->N,A->cmap->N); 9129 if (P->rmap->N != A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N); 9130 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9131 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9132 9133 if (scall == MAT_REUSE_MATRIX) { 9134 PetscValidPointer(*C,5); 9135 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9136 9137 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9138 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9139 if ((*C)->ops->ptapnumeric) { 9140 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9141 } else { 9142 ierr = MatPtAP_Basic(A,P,scall,fill,C); 9143 } 9144 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9145 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9146 PetscFunctionReturn(0); 9147 } 9148 9149 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9150 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9151 9152 fA = A->ops->ptap; 9153 fP = P->ops->ptap; 9154 ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr); 9155 if (fP == fA && sametype) { 9156 ptap = fA; 9157 } else { 9158 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9159 char ptapname[256]; 9160 ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr); 9161 ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9162 ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr); 9163 ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9164 ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9165 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9166 } 9167 9168 if (!ptap) ptap = MatPtAP_Basic; 9169 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9170 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9171 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9172 if (A->symmetric_set && A->symmetric) { 9173 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9174 } 9175 PetscFunctionReturn(0); 9176 } 9177 9178 /*@ 9179 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9180 9181 Neighbor-wise Collective on Mat 9182 9183 Input Parameters: 9184 + A - the matrix 9185 - P - the projection matrix 9186 9187 Output Parameters: 9188 . C - the product matrix 9189 9190 Notes: 9191 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9192 the user using MatDeatroy(). 9193 9194 This routine is currently only implemented for pairs of AIJ matrices and classes 9195 which inherit from AIJ. C will be of type MATAIJ. 9196 9197 Level: intermediate 9198 9199 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9200 @*/ 9201 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9202 { 9203 PetscErrorCode ierr; 9204 9205 PetscFunctionBegin; 9206 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9207 PetscValidType(A,1); 9208 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9209 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9210 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9211 PetscValidType(P,2); 9212 MatCheckPreallocated(P,2); 9213 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9214 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9215 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9216 PetscValidType(C,3); 9217 MatCheckPreallocated(C,3); 9218 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9219 if (P->cmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->rmap->N); 9220 if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N); 9221 if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 9222 if (P->cmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->cmap->N,C->cmap->N); 9223 MatCheckPreallocated(A,1); 9224 9225 if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first"); 9226 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9227 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9228 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9229 PetscFunctionReturn(0); 9230 } 9231 9232 /*@ 9233 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9234 9235 Neighbor-wise Collective on Mat 9236 9237 Input Parameters: 9238 + A - the matrix 9239 - P - the projection matrix 9240 9241 Output Parameters: 9242 . C - the (i,j) structure of the product matrix 9243 9244 Notes: 9245 C will be created and must be destroyed by the user with MatDestroy(). 9246 9247 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9248 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9249 this (i,j) structure by calling MatPtAPNumeric(). 9250 9251 Level: intermediate 9252 9253 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9254 @*/ 9255 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9256 { 9257 PetscErrorCode ierr; 9258 9259 PetscFunctionBegin; 9260 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9261 PetscValidType(A,1); 9262 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9263 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9264 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9265 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9266 PetscValidType(P,2); 9267 MatCheckPreallocated(P,2); 9268 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9269 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9270 PetscValidPointer(C,3); 9271 9272 if (P->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",P->rmap->N,A->cmap->N); 9273 if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 9274 MatCheckPreallocated(A,1); 9275 9276 if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name); 9277 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9278 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9279 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9280 9281 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9282 PetscFunctionReturn(0); 9283 } 9284 9285 /*@ 9286 MatRARt - Creates the matrix product C = R * A * R^T 9287 9288 Neighbor-wise Collective on Mat 9289 9290 Input Parameters: 9291 + A - the matrix 9292 . R - the projection matrix 9293 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9294 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9295 if the result is a dense matrix this is irrelevent 9296 9297 Output Parameters: 9298 . C - the product matrix 9299 9300 Notes: 9301 C will be created and must be destroyed by the user with MatDestroy(). 9302 9303 This routine is currently only implemented for pairs of AIJ matrices and classes 9304 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9305 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9306 We recommend using MatPtAP(). 9307 9308 Level: intermediate 9309 9310 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9311 @*/ 9312 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9313 { 9314 PetscErrorCode ierr; 9315 9316 PetscFunctionBegin; 9317 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9318 PetscValidType(A,1); 9319 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9320 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9321 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9322 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9323 PetscValidType(R,2); 9324 MatCheckPreallocated(R,2); 9325 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9326 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9327 PetscValidPointer(C,3); 9328 if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)R),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N); 9329 9330 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9331 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9332 MatCheckPreallocated(A,1); 9333 9334 if (!A->ops->rart) { 9335 Mat Rt; 9336 ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 9337 ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr); 9338 ierr = MatDestroy(&Rt);CHKERRQ(ierr); 9339 PetscFunctionReturn(0); 9340 } 9341 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9342 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9343 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9344 PetscFunctionReturn(0); 9345 } 9346 9347 /*@ 9348 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9349 9350 Neighbor-wise Collective on Mat 9351 9352 Input Parameters: 9353 + A - the matrix 9354 - R - the projection matrix 9355 9356 Output Parameters: 9357 . C - the product matrix 9358 9359 Notes: 9360 C must have been created by calling MatRARtSymbolic and must be destroyed by 9361 the user using MatDestroy(). 9362 9363 This routine is currently only implemented for pairs of AIJ matrices and classes 9364 which inherit from AIJ. C will be of type MATAIJ. 9365 9366 Level: intermediate 9367 9368 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9369 @*/ 9370 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9371 { 9372 PetscErrorCode ierr; 9373 9374 PetscFunctionBegin; 9375 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9376 PetscValidType(A,1); 9377 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9378 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9379 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9380 PetscValidType(R,2); 9381 MatCheckPreallocated(R,2); 9382 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9383 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9384 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9385 PetscValidType(C,3); 9386 MatCheckPreallocated(C,3); 9387 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9388 if (R->rmap->N!=C->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->rmap->N); 9389 if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N); 9390 if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 9391 if (R->rmap->N!=C->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->rmap->N,C->cmap->N); 9392 MatCheckPreallocated(A,1); 9393 9394 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9395 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9396 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9397 PetscFunctionReturn(0); 9398 } 9399 9400 /*@ 9401 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9402 9403 Neighbor-wise Collective on Mat 9404 9405 Input Parameters: 9406 + A - the matrix 9407 - R - the projection matrix 9408 9409 Output Parameters: 9410 . C - the (i,j) structure of the product matrix 9411 9412 Notes: 9413 C will be created and must be destroyed by the user with MatDestroy(). 9414 9415 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9416 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9417 this (i,j) structure by calling MatRARtNumeric(). 9418 9419 Level: intermediate 9420 9421 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9422 @*/ 9423 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9424 { 9425 PetscErrorCode ierr; 9426 9427 PetscFunctionBegin; 9428 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9429 PetscValidType(A,1); 9430 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9431 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9432 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9433 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9434 PetscValidType(R,2); 9435 MatCheckPreallocated(R,2); 9436 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9437 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9438 PetscValidPointer(C,3); 9439 9440 if (R->cmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",R->cmap->N,A->rmap->N); 9441 if (A->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix 'A' must be square, %D != %D",A->rmap->N,A->cmap->N); 9442 MatCheckPreallocated(A,1); 9443 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9444 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9445 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9446 9447 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9448 PetscFunctionReturn(0); 9449 } 9450 9451 /*@ 9452 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9453 9454 Neighbor-wise Collective on Mat 9455 9456 Input Parameters: 9457 + A - the left matrix 9458 . B - the right matrix 9459 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9460 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9461 if the result is a dense matrix this is irrelevent 9462 9463 Output Parameters: 9464 . C - the product matrix 9465 9466 Notes: 9467 Unless scall is MAT_REUSE_MATRIX C will be created. 9468 9469 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 9470 call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic() 9471 9472 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9473 actually needed. 9474 9475 If you have many matrices with the same non-zero structure to multiply, you 9476 should either 9477 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9478 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9479 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 9480 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9481 9482 Level: intermediate 9483 9484 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9485 @*/ 9486 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9487 { 9488 PetscErrorCode ierr; 9489 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9490 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9491 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9492 Mat T; 9493 PetscBool istrans; 9494 9495 PetscFunctionBegin; 9496 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9497 PetscValidType(A,1); 9498 MatCheckPreallocated(A,1); 9499 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9500 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9501 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9502 PetscValidType(B,2); 9503 MatCheckPreallocated(B,2); 9504 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9505 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9506 PetscValidPointer(C,3); 9507 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9508 if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 9509 ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9510 if (istrans) { 9511 ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 9512 ierr = MatTransposeMatMult(T,B,scall,fill,C);CHKERRQ(ierr); 9513 PetscFunctionReturn(0); 9514 } else { 9515 ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9516 if (istrans) { 9517 ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr); 9518 ierr = MatMatTransposeMult(A,T,scall,fill,C);CHKERRQ(ierr); 9519 PetscFunctionReturn(0); 9520 } 9521 } 9522 if (scall == MAT_REUSE_MATRIX) { 9523 PetscValidPointer(*C,5); 9524 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9525 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9526 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9527 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9528 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9529 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9530 PetscFunctionReturn(0); 9531 } 9532 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9533 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9534 9535 fA = A->ops->matmult; 9536 fB = B->ops->matmult; 9537 if (fB == fA && fB) mult = fB; 9538 else { 9539 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9540 char multname[256]; 9541 ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr); 9542 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9543 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9544 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9545 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9546 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9547 if (!mult) { 9548 ierr = PetscObjectQueryFunction((PetscObject)A,multname,&mult);CHKERRQ(ierr); 9549 } 9550 if (!mult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9551 } 9552 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9553 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9554 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9555 PetscFunctionReturn(0); 9556 } 9557 9558 /*@ 9559 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9560 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9561 9562 Neighbor-wise Collective on Mat 9563 9564 Input Parameters: 9565 + A - the left matrix 9566 . B - the right matrix 9567 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9568 if C is a dense matrix this is irrelevent 9569 9570 Output Parameters: 9571 . C - the product matrix 9572 9573 Notes: 9574 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9575 actually needed. 9576 9577 This routine is currently implemented for 9578 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9579 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9580 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9581 9582 Level: intermediate 9583 9584 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, https://arxiv.org/abs/1006.4173 9585 We should incorporate them into PETSc. 9586 9587 .seealso: MatMatMult(), MatMatMultNumeric() 9588 @*/ 9589 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9590 { 9591 PetscErrorCode ierr; 9592 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9593 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9594 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9595 9596 PetscFunctionBegin; 9597 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9598 PetscValidType(A,1); 9599 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9600 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9601 9602 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9603 PetscValidType(B,2); 9604 MatCheckPreallocated(B,2); 9605 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9606 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9607 PetscValidPointer(C,3); 9608 9609 if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 9610 if (fill == PETSC_DEFAULT) fill = 2.0; 9611 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9612 MatCheckPreallocated(A,1); 9613 9614 Asymbolic = A->ops->matmultsymbolic; 9615 Bsymbolic = B->ops->matmultsymbolic; 9616 if (Asymbolic == Bsymbolic) { 9617 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 9618 symbolic = Bsymbolic; 9619 } else { /* dispatch based on the type of A and B */ 9620 char symbolicname[256]; 9621 ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9622 ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9623 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9624 ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9625 ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr); 9626 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9627 if (!symbolic) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMultSymbolic requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9628 } 9629 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9630 *C = NULL; 9631 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 9632 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9633 PetscFunctionReturn(0); 9634 } 9635 9636 /*@ 9637 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9638 Call this routine after first calling MatMatMultSymbolic(). 9639 9640 Neighbor-wise Collective on Mat 9641 9642 Input Parameters: 9643 + A - the left matrix 9644 - B - the right matrix 9645 9646 Output Parameters: 9647 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9648 9649 Notes: 9650 C must have been created with MatMatMultSymbolic(). 9651 9652 This routine is currently implemented for 9653 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9654 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9655 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9656 9657 Level: intermediate 9658 9659 .seealso: MatMatMult(), MatMatMultSymbolic() 9660 @*/ 9661 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9662 { 9663 PetscErrorCode ierr; 9664 9665 PetscFunctionBegin; 9666 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 9667 PetscFunctionReturn(0); 9668 } 9669 9670 /*@ 9671 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9672 9673 Neighbor-wise Collective on Mat 9674 9675 Input Parameters: 9676 + A - the left matrix 9677 . B - the right matrix 9678 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9679 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9680 9681 Output Parameters: 9682 . C - the product matrix 9683 9684 Notes: 9685 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9686 9687 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9688 9689 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9690 actually needed. 9691 9692 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9693 and for pairs of MPIDense matrices. 9694 9695 Options Database Keys: 9696 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the 9697 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9698 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9699 9700 Level: intermediate 9701 9702 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9703 @*/ 9704 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9705 { 9706 PetscErrorCode ierr; 9707 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9708 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9709 Mat T; 9710 PetscBool istrans; 9711 9712 PetscFunctionBegin; 9713 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9714 PetscValidType(A,1); 9715 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9716 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9717 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9718 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9719 PetscValidType(B,2); 9720 MatCheckPreallocated(B,2); 9721 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9722 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9723 PetscValidPointer(C,3); 9724 if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N); 9725 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9726 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9727 MatCheckPreallocated(A,1); 9728 9729 ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9730 if (istrans) { 9731 ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr); 9732 ierr = MatMatMult(A,T,scall,fill,C);CHKERRQ(ierr); 9733 PetscFunctionReturn(0); 9734 } 9735 fA = A->ops->mattransposemult; 9736 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9737 fB = B->ops->mattransposemult; 9738 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9739 if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9740 9741 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9742 if (scall == MAT_INITIAL_MATRIX) { 9743 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9744 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9745 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9746 } 9747 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9748 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 9749 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9750 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9751 PetscFunctionReturn(0); 9752 } 9753 9754 /*@ 9755 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9756 9757 Neighbor-wise Collective on Mat 9758 9759 Input Parameters: 9760 + A - the left matrix 9761 . B - the right matrix 9762 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9763 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9764 9765 Output Parameters: 9766 . C - the product matrix 9767 9768 Notes: 9769 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9770 9771 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9772 9773 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9774 actually needed. 9775 9776 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9777 which inherit from SeqAIJ. C will be of same type as the input matrices. 9778 9779 Level: intermediate 9780 9781 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 9782 @*/ 9783 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9784 { 9785 PetscErrorCode ierr; 9786 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9787 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9788 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 9789 Mat T; 9790 PetscBool istrans; 9791 9792 PetscFunctionBegin; 9793 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9794 PetscValidType(A,1); 9795 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9796 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9797 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9798 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9799 PetscValidType(B,2); 9800 MatCheckPreallocated(B,2); 9801 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9802 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9803 PetscValidPointer(C,3); 9804 if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N); 9805 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9806 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9807 MatCheckPreallocated(A,1); 9808 9809 ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9810 if (istrans) { 9811 ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 9812 ierr = MatMatMult(T,B,scall,fill,C);CHKERRQ(ierr); 9813 PetscFunctionReturn(0); 9814 } 9815 fA = A->ops->transposematmult; 9816 fB = B->ops->transposematmult; 9817 if (fB == fA && fA) transposematmult = fA; 9818 else { 9819 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9820 char multname[256]; 9821 ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr); 9822 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9823 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9824 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9825 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9826 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 9827 if (!transposematmult) { 9828 ierr = PetscObjectQueryFunction((PetscObject)A,multname,&transposematmult);CHKERRQ(ierr); 9829 } 9830 if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9831 } 9832 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9833 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 9834 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9835 PetscFunctionReturn(0); 9836 } 9837 9838 /*@ 9839 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9840 9841 Neighbor-wise Collective on Mat 9842 9843 Input Parameters: 9844 + A - the left matrix 9845 . B - the middle matrix 9846 . C - the right matrix 9847 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9848 - 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 9849 if the result is a dense matrix this is irrelevent 9850 9851 Output Parameters: 9852 . D - the product matrix 9853 9854 Notes: 9855 Unless scall is MAT_REUSE_MATRIX D will be created. 9856 9857 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9858 9859 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9860 actually needed. 9861 9862 If you have many matrices with the same non-zero structure to multiply, you 9863 should use MAT_REUSE_MATRIX in all calls but the first or 9864 9865 Level: intermediate 9866 9867 .seealso: MatMatMult, MatPtAP() 9868 @*/ 9869 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9870 { 9871 PetscErrorCode ierr; 9872 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9873 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9874 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9875 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9876 9877 PetscFunctionBegin; 9878 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9879 PetscValidType(A,1); 9880 MatCheckPreallocated(A,1); 9881 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9882 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9883 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9884 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9885 PetscValidType(B,2); 9886 MatCheckPreallocated(B,2); 9887 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9888 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9889 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9890 PetscValidPointer(C,3); 9891 MatCheckPreallocated(C,3); 9892 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9893 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9894 if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 9895 if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N); 9896 if (scall == MAT_REUSE_MATRIX) { 9897 PetscValidPointer(*D,6); 9898 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 9899 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9900 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9901 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9902 PetscFunctionReturn(0); 9903 } 9904 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9905 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9906 9907 fA = A->ops->matmatmult; 9908 fB = B->ops->matmatmult; 9909 fC = C->ops->matmatmult; 9910 if (fA == fB && fA == fC) { 9911 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9912 mult = fA; 9913 } else { 9914 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 9915 char multname[256]; 9916 ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr); 9917 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9918 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9919 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9920 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9921 ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr); 9922 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); 9923 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9924 if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name); 9925 } 9926 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9927 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9928 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9929 PetscFunctionReturn(0); 9930 } 9931 9932 /*@ 9933 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9934 9935 Collective on Mat 9936 9937 Input Parameters: 9938 + mat - the matrix 9939 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9940 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 9941 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9942 9943 Output Parameter: 9944 . matredundant - redundant matrix 9945 9946 Notes: 9947 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9948 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9949 9950 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 9951 calling it. 9952 9953 Level: advanced 9954 9955 9956 .seealso: MatDestroy() 9957 @*/ 9958 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 9959 { 9960 PetscErrorCode ierr; 9961 MPI_Comm comm; 9962 PetscMPIInt size; 9963 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 9964 Mat_Redundant *redund=NULL; 9965 PetscSubcomm psubcomm=NULL; 9966 MPI_Comm subcomm_in=subcomm; 9967 Mat *matseq; 9968 IS isrow,iscol; 9969 PetscBool newsubcomm=PETSC_FALSE; 9970 9971 PetscFunctionBegin; 9972 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9973 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 9974 PetscValidPointer(*matredundant,5); 9975 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 9976 } 9977 9978 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 9979 if (size == 1 || nsubcomm == 1) { 9980 if (reuse == MAT_INITIAL_MATRIX) { 9981 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 9982 } else { 9983 if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 9984 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 9985 } 9986 PetscFunctionReturn(0); 9987 } 9988 9989 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9990 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9991 MatCheckPreallocated(mat,1); 9992 9993 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 9994 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 9995 /* create psubcomm, then get subcomm */ 9996 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 9997 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 9998 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 9999 10000 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10001 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10002 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10003 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10004 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10005 newsubcomm = PETSC_TRUE; 10006 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10007 } 10008 10009 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10010 if (reuse == MAT_INITIAL_MATRIX) { 10011 mloc_sub = PETSC_DECIDE; 10012 nloc_sub = PETSC_DECIDE; 10013 if (bs < 1) { 10014 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10015 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 10016 } else { 10017 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10018 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 10019 } 10020 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10021 rstart = rend - mloc_sub; 10022 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10023 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10024 } else { /* reuse == MAT_REUSE_MATRIX */ 10025 if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10026 /* retrieve subcomm */ 10027 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10028 redund = (*matredundant)->redundant; 10029 isrow = redund->isrow; 10030 iscol = redund->iscol; 10031 matseq = redund->matseq; 10032 } 10033 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10034 10035 /* get matredundant over subcomm */ 10036 if (reuse == MAT_INITIAL_MATRIX) { 10037 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 10038 10039 /* create a supporting struct and attach it to C for reuse */ 10040 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10041 (*matredundant)->redundant = redund; 10042 redund->isrow = isrow; 10043 redund->iscol = iscol; 10044 redund->matseq = matseq; 10045 if (newsubcomm) { 10046 redund->subcomm = subcomm; 10047 } else { 10048 redund->subcomm = MPI_COMM_NULL; 10049 } 10050 } else { 10051 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10052 } 10053 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10054 PetscFunctionReturn(0); 10055 } 10056 10057 /*@C 10058 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10059 a given 'mat' object. Each submatrix can span multiple procs. 10060 10061 Collective on Mat 10062 10063 Input Parameters: 10064 + mat - the matrix 10065 . subcomm - the subcommunicator obtained by com_split(comm) 10066 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10067 10068 Output Parameter: 10069 . subMat - 'parallel submatrices each spans a given subcomm 10070 10071 Notes: 10072 The submatrix partition across processors is dictated by 'subComm' a 10073 communicator obtained by com_split(comm). The comm_split 10074 is not restriced to be grouped with consecutive original ranks. 10075 10076 Due the comm_split() usage, the parallel layout of the submatrices 10077 map directly to the layout of the original matrix [wrt the local 10078 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10079 into the 'DiagonalMat' of the subMat, hence it is used directly from 10080 the subMat. However the offDiagMat looses some columns - and this is 10081 reconstructed with MatSetValues() 10082 10083 Level: advanced 10084 10085 10086 .seealso: MatCreateSubMatrices() 10087 @*/ 10088 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10089 { 10090 PetscErrorCode ierr; 10091 PetscMPIInt commsize,subCommSize; 10092 10093 PetscFunctionBegin; 10094 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10095 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10096 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10097 10098 if (scall == MAT_REUSE_MATRIX && *subMat == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10099 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10100 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10101 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10102 PetscFunctionReturn(0); 10103 } 10104 10105 /*@ 10106 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10107 10108 Not Collective 10109 10110 Input Arguments: 10111 + mat - matrix to extract local submatrix from 10112 . isrow - local row indices for submatrix 10113 - iscol - local column indices for submatrix 10114 10115 Output Arguments: 10116 . submat - the submatrix 10117 10118 Level: intermediate 10119 10120 Notes: 10121 The submat should be returned with MatRestoreLocalSubMatrix(). 10122 10123 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10124 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10125 10126 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10127 MatSetValuesBlockedLocal() will also be implemented. 10128 10129 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10130 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10131 10132 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10133 @*/ 10134 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10135 { 10136 PetscErrorCode ierr; 10137 10138 PetscFunctionBegin; 10139 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10140 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10141 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10142 PetscCheckSameComm(isrow,2,iscol,3); 10143 PetscValidPointer(submat,4); 10144 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10145 10146 if (mat->ops->getlocalsubmatrix) { 10147 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10148 } else { 10149 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10150 } 10151 PetscFunctionReturn(0); 10152 } 10153 10154 /*@ 10155 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10156 10157 Not Collective 10158 10159 Input Arguments: 10160 mat - matrix to extract local submatrix from 10161 isrow - local row indices for submatrix 10162 iscol - local column indices for submatrix 10163 submat - the submatrix 10164 10165 Level: intermediate 10166 10167 .seealso: MatGetLocalSubMatrix() 10168 @*/ 10169 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10170 { 10171 PetscErrorCode ierr; 10172 10173 PetscFunctionBegin; 10174 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10175 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10176 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10177 PetscCheckSameComm(isrow,2,iscol,3); 10178 PetscValidPointer(submat,4); 10179 if (*submat) { 10180 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10181 } 10182 10183 if (mat->ops->restorelocalsubmatrix) { 10184 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10185 } else { 10186 ierr = MatDestroy(submat);CHKERRQ(ierr); 10187 } 10188 *submat = NULL; 10189 PetscFunctionReturn(0); 10190 } 10191 10192 /* --------------------------------------------------------*/ 10193 /*@ 10194 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10195 10196 Collective on Mat 10197 10198 Input Parameter: 10199 . mat - the matrix 10200 10201 Output Parameter: 10202 . is - if any rows have zero diagonals this contains the list of them 10203 10204 Level: developer 10205 10206 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10207 @*/ 10208 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10209 { 10210 PetscErrorCode ierr; 10211 10212 PetscFunctionBegin; 10213 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10214 PetscValidType(mat,1); 10215 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10216 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10217 10218 if (!mat->ops->findzerodiagonals) { 10219 Vec diag; 10220 const PetscScalar *a; 10221 PetscInt *rows; 10222 PetscInt rStart, rEnd, r, nrow = 0; 10223 10224 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10225 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10226 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10227 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10228 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10229 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10230 nrow = 0; 10231 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10232 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10233 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10234 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10235 } else { 10236 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10237 } 10238 PetscFunctionReturn(0); 10239 } 10240 10241 /*@ 10242 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10243 10244 Collective on Mat 10245 10246 Input Parameter: 10247 . mat - the matrix 10248 10249 Output Parameter: 10250 . is - contains the list of rows with off block diagonal entries 10251 10252 Level: developer 10253 10254 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10255 @*/ 10256 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10257 { 10258 PetscErrorCode ierr; 10259 10260 PetscFunctionBegin; 10261 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10262 PetscValidType(mat,1); 10263 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10264 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10265 10266 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10267 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10268 PetscFunctionReturn(0); 10269 } 10270 10271 /*@C 10272 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10273 10274 Collective on Mat 10275 10276 Input Parameters: 10277 . mat - the matrix 10278 10279 Output Parameters: 10280 . values - the block inverses in column major order (FORTRAN-like) 10281 10282 Note: 10283 This routine is not available from Fortran. 10284 10285 Level: advanced 10286 10287 .seealso: MatInvertBockDiagonalMat 10288 @*/ 10289 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10290 { 10291 PetscErrorCode ierr; 10292 10293 PetscFunctionBegin; 10294 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10295 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10296 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10297 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10298 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10299 PetscFunctionReturn(0); 10300 } 10301 10302 /*@C 10303 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries. 10304 10305 Collective on Mat 10306 10307 Input Parameters: 10308 + mat - the matrix 10309 . nblocks - the number of blocks 10310 - bsizes - the size of each block 10311 10312 Output Parameters: 10313 . values - the block inverses in column major order (FORTRAN-like) 10314 10315 Note: 10316 This routine is not available from Fortran. 10317 10318 Level: advanced 10319 10320 .seealso: MatInvertBockDiagonal() 10321 @*/ 10322 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10323 { 10324 PetscErrorCode ierr; 10325 10326 PetscFunctionBegin; 10327 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10328 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10329 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10330 if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10331 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 10332 PetscFunctionReturn(0); 10333 } 10334 10335 /*@ 10336 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10337 10338 Collective on Mat 10339 10340 Input Parameters: 10341 . A - the matrix 10342 10343 Output Parameters: 10344 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10345 10346 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10347 10348 Level: advanced 10349 10350 .seealso: MatInvertBockDiagonal() 10351 @*/ 10352 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10353 { 10354 PetscErrorCode ierr; 10355 const PetscScalar *vals; 10356 PetscInt *dnnz; 10357 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10358 10359 PetscFunctionBegin; 10360 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10361 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10362 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10363 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10364 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10365 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10366 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10367 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10368 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10369 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10370 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10371 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10372 for (i = rstart/bs; i < rend/bs; i++) { 10373 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10374 } 10375 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10376 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10377 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10378 PetscFunctionReturn(0); 10379 } 10380 10381 /*@C 10382 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10383 via MatTransposeColoringCreate(). 10384 10385 Collective on MatTransposeColoring 10386 10387 Input Parameter: 10388 . c - coloring context 10389 10390 Level: intermediate 10391 10392 .seealso: MatTransposeColoringCreate() 10393 @*/ 10394 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10395 { 10396 PetscErrorCode ierr; 10397 MatTransposeColoring matcolor=*c; 10398 10399 PetscFunctionBegin; 10400 if (!matcolor) PetscFunctionReturn(0); 10401 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10402 10403 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10404 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10405 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10406 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10407 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10408 if (matcolor->brows>0) { 10409 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10410 } 10411 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10412 PetscFunctionReturn(0); 10413 } 10414 10415 /*@C 10416 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10417 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10418 MatTransposeColoring to sparse B. 10419 10420 Collective on MatTransposeColoring 10421 10422 Input Parameters: 10423 + B - sparse matrix B 10424 . Btdense - symbolic dense matrix B^T 10425 - coloring - coloring context created with MatTransposeColoringCreate() 10426 10427 Output Parameter: 10428 . Btdense - dense matrix B^T 10429 10430 Level: advanced 10431 10432 Notes: 10433 These are used internally for some implementations of MatRARt() 10434 10435 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10436 10437 @*/ 10438 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10439 { 10440 PetscErrorCode ierr; 10441 10442 PetscFunctionBegin; 10443 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10444 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10445 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10446 10447 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10448 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10449 PetscFunctionReturn(0); 10450 } 10451 10452 /*@C 10453 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10454 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10455 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10456 Csp from Cden. 10457 10458 Collective on MatTransposeColoring 10459 10460 Input Parameters: 10461 + coloring - coloring context created with MatTransposeColoringCreate() 10462 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10463 10464 Output Parameter: 10465 . Csp - sparse matrix 10466 10467 Level: advanced 10468 10469 Notes: 10470 These are used internally for some implementations of MatRARt() 10471 10472 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10473 10474 @*/ 10475 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10476 { 10477 PetscErrorCode ierr; 10478 10479 PetscFunctionBegin; 10480 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10481 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10482 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10483 10484 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10485 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10486 PetscFunctionReturn(0); 10487 } 10488 10489 /*@C 10490 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10491 10492 Collective on Mat 10493 10494 Input Parameters: 10495 + mat - the matrix product C 10496 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10497 10498 Output Parameter: 10499 . color - the new coloring context 10500 10501 Level: intermediate 10502 10503 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10504 MatTransColoringApplyDenToSp() 10505 @*/ 10506 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10507 { 10508 MatTransposeColoring c; 10509 MPI_Comm comm; 10510 PetscErrorCode ierr; 10511 10512 PetscFunctionBegin; 10513 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10514 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10515 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10516 10517 c->ctype = iscoloring->ctype; 10518 if (mat->ops->transposecoloringcreate) { 10519 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10520 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10521 10522 *color = c; 10523 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10524 PetscFunctionReturn(0); 10525 } 10526 10527 /*@ 10528 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10529 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10530 same, otherwise it will be larger 10531 10532 Not Collective 10533 10534 Input Parameter: 10535 . A - the matrix 10536 10537 Output Parameter: 10538 . state - the current state 10539 10540 Notes: 10541 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10542 different matrices 10543 10544 Level: intermediate 10545 10546 @*/ 10547 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10548 { 10549 PetscFunctionBegin; 10550 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10551 *state = mat->nonzerostate; 10552 PetscFunctionReturn(0); 10553 } 10554 10555 /*@ 10556 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10557 matrices from each processor 10558 10559 Collective 10560 10561 Input Parameters: 10562 + comm - the communicators the parallel matrix will live on 10563 . seqmat - the input sequential matrices 10564 . n - number of local columns (or PETSC_DECIDE) 10565 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10566 10567 Output Parameter: 10568 . mpimat - the parallel matrix generated 10569 10570 Level: advanced 10571 10572 Notes: 10573 The number of columns of the matrix in EACH processor MUST be the same. 10574 10575 @*/ 10576 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10577 { 10578 PetscErrorCode ierr; 10579 10580 PetscFunctionBegin; 10581 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10582 if (reuse == MAT_REUSE_MATRIX && seqmat == *mpimat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10583 10584 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10585 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10586 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10587 PetscFunctionReturn(0); 10588 } 10589 10590 /*@ 10591 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10592 ranks' ownership ranges. 10593 10594 Collective on A 10595 10596 Input Parameters: 10597 + A - the matrix to create subdomains from 10598 - N - requested number of subdomains 10599 10600 10601 Output Parameters: 10602 + n - number of subdomains resulting on this rank 10603 - iss - IS list with indices of subdomains on this rank 10604 10605 Level: advanced 10606 10607 Notes: 10608 number of subdomains must be smaller than the communicator size 10609 @*/ 10610 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10611 { 10612 MPI_Comm comm,subcomm; 10613 PetscMPIInt size,rank,color; 10614 PetscInt rstart,rend,k; 10615 PetscErrorCode ierr; 10616 10617 PetscFunctionBegin; 10618 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10619 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10620 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10621 if (N < 1 || N >= (PetscInt)size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %D, got N = %D",size,N); 10622 *n = 1; 10623 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10624 color = rank/k; 10625 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10626 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10627 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10628 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10629 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10630 PetscFunctionReturn(0); 10631 } 10632 10633 /*@ 10634 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10635 10636 If the interpolation and restriction operators are the same, uses MatPtAP. 10637 If they are not the same, use MatMatMatMult. 10638 10639 Once the coarse grid problem is constructed, correct for interpolation operators 10640 that are not of full rank, which can legitimately happen in the case of non-nested 10641 geometric multigrid. 10642 10643 Input Parameters: 10644 + restrct - restriction operator 10645 . dA - fine grid matrix 10646 . interpolate - interpolation operator 10647 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10648 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10649 10650 Output Parameters: 10651 . A - the Galerkin coarse matrix 10652 10653 Options Database Key: 10654 . -pc_mg_galerkin <both,pmat,mat,none> 10655 10656 Level: developer 10657 10658 .seealso: MatPtAP(), MatMatMatMult() 10659 @*/ 10660 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10661 { 10662 PetscErrorCode ierr; 10663 IS zerorows; 10664 Vec diag; 10665 10666 PetscFunctionBegin; 10667 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10668 /* Construct the coarse grid matrix */ 10669 if (interpolate == restrct) { 10670 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10671 } else { 10672 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10673 } 10674 10675 /* If the interpolation matrix is not of full rank, A will have zero rows. 10676 This can legitimately happen in the case of non-nested geometric multigrid. 10677 In that event, we set the rows of the matrix to the rows of the identity, 10678 ignoring the equations (as the RHS will also be zero). */ 10679 10680 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10681 10682 if (zerorows != NULL) { /* if there are any zero rows */ 10683 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10684 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10685 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10686 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10687 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10688 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10689 } 10690 PetscFunctionReturn(0); 10691 } 10692 10693 /*@C 10694 MatSetOperation - Allows user to set a matrix operation for any matrix type 10695 10696 Logically Collective on Mat 10697 10698 Input Parameters: 10699 + mat - the matrix 10700 . op - the name of the operation 10701 - f - the function that provides the operation 10702 10703 Level: developer 10704 10705 Usage: 10706 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10707 $ ierr = MatCreateXXX(comm,...&A); 10708 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10709 10710 Notes: 10711 See the file include/petscmat.h for a complete list of matrix 10712 operations, which all have the form MATOP_<OPERATION>, where 10713 <OPERATION> is the name (in all capital letters) of the 10714 user interface routine (e.g., MatMult() -> MATOP_MULT). 10715 10716 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10717 sequence as the usual matrix interface routines, since they 10718 are intended to be accessed via the usual matrix interface 10719 routines, e.g., 10720 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10721 10722 In particular each function MUST return an error code of 0 on success and 10723 nonzero on failure. 10724 10725 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10726 10727 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10728 @*/ 10729 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10730 { 10731 PetscFunctionBegin; 10732 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10733 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10734 mat->ops->viewnative = mat->ops->view; 10735 } 10736 (((void(**)(void))mat->ops)[op]) = f; 10737 PetscFunctionReturn(0); 10738 } 10739 10740 /*@C 10741 MatGetOperation - Gets a matrix operation for any matrix type. 10742 10743 Not Collective 10744 10745 Input Parameters: 10746 + mat - the matrix 10747 - op - the name of the operation 10748 10749 Output Parameter: 10750 . f - the function that provides the operation 10751 10752 Level: developer 10753 10754 Usage: 10755 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10756 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10757 10758 Notes: 10759 See the file include/petscmat.h for a complete list of matrix 10760 operations, which all have the form MATOP_<OPERATION>, where 10761 <OPERATION> is the name (in all capital letters) of the 10762 user interface routine (e.g., MatMult() -> MATOP_MULT). 10763 10764 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10765 10766 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 10767 @*/ 10768 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10769 { 10770 PetscFunctionBegin; 10771 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10772 *f = (((void (**)(void))mat->ops)[op]); 10773 PetscFunctionReturn(0); 10774 } 10775 10776 /*@ 10777 MatHasOperation - Determines whether the given matrix supports the particular 10778 operation. 10779 10780 Not Collective 10781 10782 Input Parameters: 10783 + mat - the matrix 10784 - op - the operation, for example, MATOP_GET_DIAGONAL 10785 10786 Output Parameter: 10787 . has - either PETSC_TRUE or PETSC_FALSE 10788 10789 Level: advanced 10790 10791 Notes: 10792 See the file include/petscmat.h for a complete list of matrix 10793 operations, which all have the form MATOP_<OPERATION>, where 10794 <OPERATION> is the name (in all capital letters) of the 10795 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10796 10797 .seealso: MatCreateShell() 10798 @*/ 10799 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10800 { 10801 PetscErrorCode ierr; 10802 10803 PetscFunctionBegin; 10804 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10805 PetscValidType(mat,1); 10806 PetscValidPointer(has,3); 10807 if (mat->ops->hasoperation) { 10808 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 10809 } else { 10810 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10811 else { 10812 *has = PETSC_FALSE; 10813 if (op == MATOP_CREATE_SUBMATRIX) { 10814 PetscMPIInt size; 10815 10816 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10817 if (size == 1) { 10818 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 10819 } 10820 } 10821 } 10822 } 10823 PetscFunctionReturn(0); 10824 } 10825 10826 /*@ 10827 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10828 of the matrix are congruent 10829 10830 Collective on mat 10831 10832 Input Parameters: 10833 . mat - the matrix 10834 10835 Output Parameter: 10836 . cong - either PETSC_TRUE or PETSC_FALSE 10837 10838 Level: beginner 10839 10840 Notes: 10841 10842 .seealso: MatCreate(), MatSetSizes() 10843 @*/ 10844 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 10845 { 10846 PetscErrorCode ierr; 10847 10848 PetscFunctionBegin; 10849 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10850 PetscValidType(mat,1); 10851 PetscValidPointer(cong,2); 10852 if (!mat->rmap || !mat->cmap) { 10853 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10854 PetscFunctionReturn(0); 10855 } 10856 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10857 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 10858 if (*cong) mat->congruentlayouts = 1; 10859 else mat->congruentlayouts = 0; 10860 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10861 PetscFunctionReturn(0); 10862 } 10863 10864 /*@ 10865 MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse, 10866 e.g., matrx product of MatPtAP. 10867 10868 Collective on mat 10869 10870 Input Parameters: 10871 . mat - the matrix 10872 10873 Output Parameter: 10874 . mat - the matrix with intermediate data structures released 10875 10876 Level: advanced 10877 10878 Notes: 10879 10880 .seealso: MatPtAP(), MatMatMult() 10881 @*/ 10882 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat) 10883 { 10884 PetscErrorCode ierr; 10885 10886 PetscFunctionBegin; 10887 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10888 PetscValidType(mat,1); 10889 if (mat->ops->freeintermediatedatastructures) { 10890 ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr); 10891 } 10892 PetscFunctionReturn(0); 10893 } 10894