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