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 MAT_FactorFactS,MAT_FactorInvS; 40 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 41 42 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0}; 43 44 /*@ 45 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, 46 for sparse matrices that already have locations it fills the locations with random numbers 47 48 Logically Collective on Mat 49 50 Input Parameters: 51 + x - the matrix 52 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 53 it will create one internally. 54 55 Output Parameter: 56 . x - the matrix 57 58 Example of Usage: 59 .vb 60 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 61 MatSetRandom(x,rctx); 62 PetscRandomDestroy(rctx); 63 .ve 64 65 Level: intermediate 66 67 68 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy() 69 @*/ 70 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 71 { 72 PetscErrorCode ierr; 73 PetscRandom randObj = NULL; 74 75 PetscFunctionBegin; 76 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 77 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 78 PetscValidType(x,1); 79 80 if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 81 82 if (!rctx) { 83 MPI_Comm comm; 84 ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 85 ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr); 86 ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr); 87 rctx = randObj; 88 } 89 90 ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 91 ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr); 92 ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 93 94 ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 95 ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 96 ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr); 97 PetscFunctionReturn(0); 98 } 99 100 /*@ 101 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 102 103 Logically Collective on Mat 104 105 Input Parameters: 106 . mat - the factored matrix 107 108 Output Parameter: 109 + pivot - the pivot value computed 110 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 111 the share the matrix 112 113 Level: advanced 114 115 Notes: 116 This routine does not work for factorizations done with external packages. 117 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 118 119 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 120 121 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 122 @*/ 123 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 124 { 125 PetscFunctionBegin; 126 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 127 *pivot = mat->factorerror_zeropivot_value; 128 *row = mat->factorerror_zeropivot_row; 129 PetscFunctionReturn(0); 130 } 131 132 /*@ 133 MatFactorGetError - gets the error code from a factorization 134 135 Logically Collective on Mat 136 137 Input Parameters: 138 . mat - the factored matrix 139 140 Output Parameter: 141 . err - the error code 142 143 Level: advanced 144 145 Notes: 146 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 147 148 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 149 @*/ 150 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 151 { 152 PetscFunctionBegin; 153 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 154 *err = mat->factorerrortype; 155 PetscFunctionReturn(0); 156 } 157 158 /*@ 159 MatFactorClearError - clears the error code in a factorization 160 161 Logically Collective on Mat 162 163 Input Parameter: 164 . mat - the factored matrix 165 166 Level: developer 167 168 Notes: 169 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 170 171 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot() 172 @*/ 173 PetscErrorCode MatFactorClearError(Mat mat) 174 { 175 PetscFunctionBegin; 176 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 177 mat->factorerrortype = MAT_FACTOR_NOERROR; 178 mat->factorerror_zeropivot_value = 0.0; 179 mat->factorerror_zeropivot_row = 0; 180 PetscFunctionReturn(0); 181 } 182 183 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 184 { 185 PetscErrorCode ierr; 186 Vec r,l; 187 const PetscScalar *al; 188 PetscInt i,nz,gnz,N,n; 189 190 PetscFunctionBegin; 191 ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr); 192 if (!cols) { /* nonzero rows */ 193 ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 194 ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr); 195 ierr = VecSet(l,0.0);CHKERRQ(ierr); 196 ierr = VecSetRandom(r,NULL);CHKERRQ(ierr); 197 ierr = MatMult(mat,r,l);CHKERRQ(ierr); 198 ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr); 199 } else { /* nonzero columns */ 200 ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr); 201 ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr); 202 ierr = VecSet(r,0.0);CHKERRQ(ierr); 203 ierr = VecSetRandom(l,NULL);CHKERRQ(ierr); 204 ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr); 205 ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr); 206 } 207 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 208 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 209 ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 210 if (gnz != N) { 211 PetscInt *nzr; 212 ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr); 213 if (nz) { 214 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 215 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 216 } 217 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr); 218 } else *nonzero = NULL; 219 if (!cols) { /* nonzero rows */ 220 ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr); 221 } else { 222 ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr); 223 } 224 ierr = VecDestroy(&l);CHKERRQ(ierr); 225 ierr = VecDestroy(&r);CHKERRQ(ierr); 226 PetscFunctionReturn(0); 227 } 228 229 /*@ 230 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 231 232 Input Parameter: 233 . A - the matrix 234 235 Output Parameter: 236 . keptrows - the rows that are not completely zero 237 238 Notes: 239 keptrows is set to NULL if all rows are nonzero. 240 241 Level: intermediate 242 243 @*/ 244 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 245 { 246 PetscErrorCode ierr; 247 248 PetscFunctionBegin; 249 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 250 PetscValidType(mat,1); 251 PetscValidPointer(keptrows,2); 252 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 253 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 254 if (!mat->ops->findnonzerorows) { 255 ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr); 256 } else { 257 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr); 258 } 259 PetscFunctionReturn(0); 260 } 261 262 /*@ 263 MatFindZeroRows - Locate all rows that are completely zero in the matrix 264 265 Input Parameter: 266 . A - the matrix 267 268 Output Parameter: 269 . zerorows - the rows that are completely zero 270 271 Notes: 272 zerorows is set to NULL if no rows are zero. 273 274 Level: intermediate 275 276 @*/ 277 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 278 { 279 PetscErrorCode ierr; 280 IS keptrows; 281 PetscInt m, n; 282 283 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 284 PetscValidType(mat,1); 285 286 ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr); 287 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 288 In keeping with this convention, we set zerorows to NULL if there are no zero 289 rows. */ 290 if (keptrows == NULL) { 291 *zerorows = NULL; 292 } else { 293 ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr); 294 ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr); 295 ierr = ISDestroy(&keptrows);CHKERRQ(ierr); 296 } 297 PetscFunctionReturn(0); 298 } 299 300 /*@ 301 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 302 303 Not Collective 304 305 Input Parameters: 306 . A - the matrix 307 308 Output Parameters: 309 . a - the diagonal part (which is a SEQUENTIAL matrix) 310 311 Notes: 312 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 313 Use caution, as the reference count on the returned matrix is not incremented and it is used as 314 part of the containing MPI Mat's normal operation. 315 316 Level: advanced 317 318 @*/ 319 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 320 { 321 PetscErrorCode ierr; 322 323 PetscFunctionBegin; 324 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 325 PetscValidType(A,1); 326 PetscValidPointer(a,3); 327 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 328 if (!A->ops->getdiagonalblock) { 329 PetscMPIInt size; 330 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 331 if (size == 1) { 332 *a = A; 333 PetscFunctionReturn(0); 334 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type"); 335 } 336 ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr); 337 PetscFunctionReturn(0); 338 } 339 340 /*@ 341 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 342 343 Collective on Mat 344 345 Input Parameters: 346 . mat - the matrix 347 348 Output Parameter: 349 . trace - the sum of the diagonal entries 350 351 Level: advanced 352 353 @*/ 354 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 355 { 356 PetscErrorCode ierr; 357 Vec diag; 358 359 PetscFunctionBegin; 360 ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr); 361 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr); 362 ierr = VecSum(diag,trace);CHKERRQ(ierr); 363 ierr = VecDestroy(&diag);CHKERRQ(ierr); 364 PetscFunctionReturn(0); 365 } 366 367 /*@ 368 MatRealPart - Zeros out the imaginary part of the matrix 369 370 Logically Collective on Mat 371 372 Input Parameters: 373 . mat - the matrix 374 375 Level: advanced 376 377 378 .seealso: MatImaginaryPart() 379 @*/ 380 PetscErrorCode MatRealPart(Mat mat) 381 { 382 PetscErrorCode ierr; 383 384 PetscFunctionBegin; 385 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 386 PetscValidType(mat,1); 387 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 388 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 389 if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 390 MatCheckPreallocated(mat,1); 391 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr); 392 PetscFunctionReturn(0); 393 } 394 395 /*@C 396 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 397 398 Collective on Mat 399 400 Input Parameter: 401 . mat - the matrix 402 403 Output Parameters: 404 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 405 - ghosts - the global indices of the ghost points 406 407 Notes: 408 the nghosts and ghosts are suitable to pass into VecCreateGhost() 409 410 Level: advanced 411 412 @*/ 413 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 414 { 415 PetscErrorCode ierr; 416 417 PetscFunctionBegin; 418 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 419 PetscValidType(mat,1); 420 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 421 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 422 if (!mat->ops->getghosts) { 423 if (nghosts) *nghosts = 0; 424 if (ghosts) *ghosts = 0; 425 } else { 426 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr); 427 } 428 PetscFunctionReturn(0); 429 } 430 431 432 /*@ 433 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 434 435 Logically Collective on Mat 436 437 Input Parameters: 438 . mat - the matrix 439 440 Level: advanced 441 442 443 .seealso: MatRealPart() 444 @*/ 445 PetscErrorCode MatImaginaryPart(Mat mat) 446 { 447 PetscErrorCode ierr; 448 449 PetscFunctionBegin; 450 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 451 PetscValidType(mat,1); 452 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 453 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 454 if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 455 MatCheckPreallocated(mat,1); 456 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr); 457 PetscFunctionReturn(0); 458 } 459 460 /*@ 461 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 462 463 Not Collective 464 465 Input Parameter: 466 . mat - the matrix 467 468 Output Parameters: 469 + missing - is any diagonal missing 470 - dd - first diagonal entry that is missing (optional) on this process 471 472 Level: advanced 473 474 475 .seealso: MatRealPart() 476 @*/ 477 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 478 { 479 PetscErrorCode ierr; 480 481 PetscFunctionBegin; 482 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 483 PetscValidType(mat,1); 484 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 485 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 486 if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 487 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr); 488 PetscFunctionReturn(0); 489 } 490 491 /*@C 492 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 493 for each row that you get to ensure that your application does 494 not bleed memory. 495 496 Not Collective 497 498 Input Parameters: 499 + mat - the matrix 500 - row - the row to get 501 502 Output Parameters: 503 + ncols - if not NULL, the number of nonzeros in the row 504 . cols - if not NULL, the column numbers 505 - vals - if not NULL, the values 506 507 Notes: 508 This routine is provided for people who need to have direct access 509 to the structure of a matrix. We hope that we provide enough 510 high-level matrix routines that few users will need it. 511 512 MatGetRow() always returns 0-based column indices, regardless of 513 whether the internal representation is 0-based (default) or 1-based. 514 515 For better efficiency, set cols and/or vals to NULL if you do 516 not wish to extract these quantities. 517 518 The user can only examine the values extracted with MatGetRow(); 519 the values cannot be altered. To change the matrix entries, one 520 must use MatSetValues(). 521 522 You can only have one call to MatGetRow() outstanding for a particular 523 matrix at a time, per processor. MatGetRow() can only obtain rows 524 associated with the given processor, it cannot get rows from the 525 other processors; for that we suggest using MatCreateSubMatrices(), then 526 MatGetRow() on the submatrix. The row index passed to MatGetRow() 527 is in the global number of rows. 528 529 Fortran Notes: 530 The calling sequence from Fortran is 531 .vb 532 MatGetRow(matrix,row,ncols,cols,values,ierr) 533 Mat matrix (input) 534 integer row (input) 535 integer ncols (output) 536 integer cols(maxcols) (output) 537 double precision (or double complex) values(maxcols) output 538 .ve 539 where maxcols >= maximum nonzeros in any row of the matrix. 540 541 542 Caution: 543 Do not try to change the contents of the output arrays (cols and vals). 544 In some cases, this may corrupt the matrix. 545 546 Level: advanced 547 548 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal() 549 @*/ 550 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 551 { 552 PetscErrorCode ierr; 553 PetscInt incols; 554 555 PetscFunctionBegin; 556 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 557 PetscValidType(mat,1); 558 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 559 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 560 if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 561 MatCheckPreallocated(mat,1); 562 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 563 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr); 564 if (ncols) *ncols = incols; 565 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 566 PetscFunctionReturn(0); 567 } 568 569 /*@ 570 MatConjugate - replaces the matrix values with their complex conjugates 571 572 Logically Collective on Mat 573 574 Input Parameters: 575 . mat - the matrix 576 577 Level: advanced 578 579 .seealso: VecConjugate() 580 @*/ 581 PetscErrorCode MatConjugate(Mat mat) 582 { 583 #if defined(PETSC_USE_COMPLEX) 584 PetscErrorCode ierr; 585 586 PetscFunctionBegin; 587 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 588 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 589 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"); 590 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr); 591 #else 592 PetscFunctionBegin; 593 #endif 594 PetscFunctionReturn(0); 595 } 596 597 /*@C 598 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 599 600 Not Collective 601 602 Input Parameters: 603 + mat - the matrix 604 . row - the row to get 605 . ncols, cols - the number of nonzeros and their columns 606 - vals - if nonzero the column values 607 608 Notes: 609 This routine should be called after you have finished examining the entries. 610 611 This routine zeros out ncols, cols, and vals. This is to prevent accidental 612 us of the array after it has been restored. If you pass NULL, it will 613 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 614 615 Fortran Notes: 616 The calling sequence from Fortran is 617 .vb 618 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 619 Mat matrix (input) 620 integer row (input) 621 integer ncols (output) 622 integer cols(maxcols) (output) 623 double precision (or double complex) values(maxcols) output 624 .ve 625 Where maxcols >= maximum nonzeros in any row of the matrix. 626 627 In Fortran MatRestoreRow() MUST be called after MatGetRow() 628 before another call to MatGetRow() can be made. 629 630 Level: advanced 631 632 .seealso: MatGetRow() 633 @*/ 634 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 635 { 636 PetscErrorCode ierr; 637 638 PetscFunctionBegin; 639 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 640 if (ncols) PetscValidIntPointer(ncols,3); 641 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 642 if (!mat->ops->restorerow) PetscFunctionReturn(0); 643 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 644 if (ncols) *ncols = 0; 645 if (cols) *cols = NULL; 646 if (vals) *vals = NULL; 647 PetscFunctionReturn(0); 648 } 649 650 /*@ 651 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 652 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 653 654 Not Collective 655 656 Input Parameters: 657 . mat - the matrix 658 659 Notes: 660 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. 661 662 Level: advanced 663 664 .seealso: MatRestoreRowUpperTriangular() 665 @*/ 666 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 667 { 668 PetscErrorCode ierr; 669 670 PetscFunctionBegin; 671 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 672 PetscValidType(mat,1); 673 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 674 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 675 MatCheckPreallocated(mat,1); 676 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 677 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr); 678 PetscFunctionReturn(0); 679 } 680 681 /*@ 682 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 683 684 Not Collective 685 686 Input Parameters: 687 . mat - the matrix 688 689 Notes: 690 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 691 692 693 Level: advanced 694 695 .seealso: MatGetRowUpperTriangular() 696 @*/ 697 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 698 { 699 PetscErrorCode ierr; 700 701 PetscFunctionBegin; 702 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 703 PetscValidType(mat,1); 704 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 705 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 706 MatCheckPreallocated(mat,1); 707 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 708 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr); 709 PetscFunctionReturn(0); 710 } 711 712 /*@C 713 MatSetOptionsPrefix - Sets the prefix used for searching for all 714 Mat options in the database. 715 716 Logically Collective on Mat 717 718 Input Parameter: 719 + A - the Mat context 720 - prefix - the prefix to prepend to all option names 721 722 Notes: 723 A hyphen (-) must NOT be given at the beginning of the prefix name. 724 The first character of all runtime options is AUTOMATICALLY the hyphen. 725 726 Level: advanced 727 728 .seealso: MatSetFromOptions() 729 @*/ 730 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 731 { 732 PetscErrorCode ierr; 733 734 PetscFunctionBegin; 735 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 736 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 737 PetscFunctionReturn(0); 738 } 739 740 /*@C 741 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 742 Mat options in the database. 743 744 Logically Collective on Mat 745 746 Input Parameters: 747 + A - the Mat context 748 - prefix - the prefix to prepend to all option names 749 750 Notes: 751 A hyphen (-) must NOT be given at the beginning of the prefix name. 752 The first character of all runtime options is AUTOMATICALLY the hyphen. 753 754 Level: advanced 755 756 .seealso: MatGetOptionsPrefix() 757 @*/ 758 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 759 { 760 PetscErrorCode ierr; 761 762 PetscFunctionBegin; 763 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 764 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 765 PetscFunctionReturn(0); 766 } 767 768 /*@C 769 MatGetOptionsPrefix - Sets the prefix used for searching for all 770 Mat options in the database. 771 772 Not Collective 773 774 Input Parameter: 775 . A - the Mat context 776 777 Output Parameter: 778 . prefix - pointer to the prefix string used 779 780 Notes: 781 On the fortran side, the user should pass in a string 'prefix' of 782 sufficient length to hold the prefix. 783 784 Level: advanced 785 786 .seealso: MatAppendOptionsPrefix() 787 @*/ 788 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 789 { 790 PetscErrorCode ierr; 791 792 PetscFunctionBegin; 793 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 794 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 795 PetscFunctionReturn(0); 796 } 797 798 /*@ 799 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 800 801 Collective on Mat 802 803 Input Parameters: 804 . A - the Mat context 805 806 Notes: 807 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 808 Currently support MPIAIJ and SEQAIJ. 809 810 Level: beginner 811 812 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation() 813 @*/ 814 PetscErrorCode MatResetPreallocation(Mat A) 815 { 816 PetscErrorCode ierr; 817 818 PetscFunctionBegin; 819 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 820 PetscValidType(A,1); 821 ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr); 822 PetscFunctionReturn(0); 823 } 824 825 826 /*@ 827 MatSetUp - Sets up the internal matrix data structures for the later use. 828 829 Collective on Mat 830 831 Input Parameters: 832 . A - the Mat context 833 834 Notes: 835 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 836 837 If a suitable preallocation routine is used, this function does not need to be called. 838 839 See the Performance chapter of the PETSc users manual for how to preallocate matrices 840 841 Level: beginner 842 843 .seealso: MatCreate(), MatDestroy() 844 @*/ 845 PetscErrorCode MatSetUp(Mat A) 846 { 847 PetscMPIInt size; 848 PetscErrorCode ierr; 849 850 PetscFunctionBegin; 851 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 852 if (!((PetscObject)A)->type_name) { 853 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr); 854 if (size == 1) { 855 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr); 856 } else { 857 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr); 858 } 859 } 860 if (!A->preallocated && A->ops->setup) { 861 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 862 ierr = (*A->ops->setup)(A);CHKERRQ(ierr); 863 } 864 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 865 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 866 A->preallocated = PETSC_TRUE; 867 PetscFunctionReturn(0); 868 } 869 870 #if defined(PETSC_HAVE_SAWS) 871 #include <petscviewersaws.h> 872 #endif 873 /*@C 874 MatView - Visualizes a matrix object. 875 876 Collective on Mat 877 878 Input Parameters: 879 + mat - the matrix 880 - viewer - visualization context 881 882 Notes: 883 The available visualization contexts include 884 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 885 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 886 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 887 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 888 889 The user can open alternative visualization contexts with 890 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 891 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 892 specified file; corresponding input uses MatLoad() 893 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 894 an X window display 895 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 896 Currently only the sequential dense and AIJ 897 matrix types support the Socket viewer. 898 899 The user can call PetscViewerPushFormat() to specify the output 900 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 901 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 902 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 903 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 904 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 905 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 906 format common among all matrix types 907 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 908 format (which is in many cases the same as the default) 909 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 910 size and structure (not the matrix entries) 911 - PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 912 the matrix structure 913 914 Options Database Keys: 915 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 916 . -mat_view ::ascii_info_detail - Prints more detailed info 917 . -mat_view - Prints matrix in ASCII format 918 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 919 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 920 . -display <name> - Sets display name (default is host) 921 . -draw_pause <sec> - Sets number of seconds to pause after display 922 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 923 . -viewer_socket_machine <machine> - 924 . -viewer_socket_port <port> - 925 . -mat_view binary - save matrix to file in binary format 926 - -viewer_binary_filename <name> - 927 Level: beginner 928 929 Notes: 930 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 931 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 932 933 See the manual page for MatLoad() for the exact format of the binary file when the binary 934 viewer is used. 935 936 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 937 viewer is used. 938 939 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 940 and then use the following mouse functions. 941 + left mouse: zoom in 942 . middle mouse: zoom out 943 - right mouse: continue with the simulation 944 945 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 946 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 947 @*/ 948 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 949 { 950 PetscErrorCode ierr; 951 PetscInt rows,cols,rbs,cbs; 952 PetscBool iascii,ibinary,isstring; 953 PetscViewerFormat format; 954 PetscMPIInt size; 955 #if defined(PETSC_HAVE_SAWS) 956 PetscBool issaws; 957 #endif 958 959 PetscFunctionBegin; 960 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 961 PetscValidType(mat,1); 962 if (!viewer) { 963 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr); 964 } 965 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 966 PetscCheckSameComm(mat,1,viewer,2); 967 MatCheckPreallocated(mat,1); 968 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 969 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 970 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 971 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 972 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 973 if (ibinary) { 974 PetscBool mpiio; 975 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr); 976 if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag"); 977 } 978 979 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 980 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 981 if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 982 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed"); 983 } 984 985 #if defined(PETSC_HAVE_SAWS) 986 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 987 #endif 988 if (iascii) { 989 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 990 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr); 991 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 992 MatNullSpace nullsp,transnullsp; 993 994 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 995 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 996 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 997 if (rbs != 1 || cbs != 1) { 998 if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);} 999 else {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);} 1000 } else { 1001 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr); 1002 } 1003 if (mat->factortype) { 1004 MatSolverType solver; 1005 ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr); 1006 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr); 1007 } 1008 if (mat->ops->getinfo) { 1009 MatInfo info; 1010 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 1011 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr); 1012 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr); 1013 } 1014 ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr); 1015 ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr); 1016 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);} 1017 if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached transposed null space\n");CHKERRQ(ierr);} 1018 ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr); 1019 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached near null space\n");CHKERRQ(ierr);} 1020 } 1021 #if defined(PETSC_HAVE_SAWS) 1022 } else if (issaws) { 1023 PetscMPIInt rank; 1024 1025 ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr); 1026 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1027 if (!((PetscObject)mat)->amsmem && !rank) { 1028 ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr); 1029 } 1030 #endif 1031 } else if (isstring) { 1032 const char *type; 1033 ierr = MatGetType(mat,&type);CHKERRQ(ierr); 1034 ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr); 1035 if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);} 1036 } 1037 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1038 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1039 ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr); 1040 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1041 } else if (mat->ops->view) { 1042 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1043 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 1044 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1045 } 1046 if (iascii) { 1047 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1048 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1049 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1050 } 1051 } 1052 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1053 PetscFunctionReturn(0); 1054 } 1055 1056 #if defined(PETSC_USE_DEBUG) 1057 #include <../src/sys/totalview/tv_data_display.h> 1058 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1059 { 1060 TV_add_row("Local rows", "int", &mat->rmap->n); 1061 TV_add_row("Local columns", "int", &mat->cmap->n); 1062 TV_add_row("Global rows", "int", &mat->rmap->N); 1063 TV_add_row("Global columns", "int", &mat->cmap->N); 1064 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1065 return TV_format_OK; 1066 } 1067 #endif 1068 1069 /*@C 1070 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1071 with MatView(). The matrix format is determined from the options database. 1072 Generates a parallel MPI matrix if the communicator has more than one 1073 processor. The default matrix type is AIJ. 1074 1075 Collective on PetscViewer 1076 1077 Input Parameters: 1078 + newmat - the newly loaded matrix, this needs to have been created with MatCreate() 1079 or some related function before a call to MatLoad() 1080 - viewer - binary/HDF5 file viewer 1081 1082 Options Database Keys: 1083 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1084 block size 1085 . -matload_block_size <bs> 1086 1087 Level: beginner 1088 1089 Notes: 1090 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1091 Mat before calling this routine if you wish to set it from the options database. 1092 1093 MatLoad() automatically loads into the options database any options 1094 given in the file filename.info where filename is the name of the file 1095 that was passed to the PetscViewerBinaryOpen(). The options in the info 1096 file will be ignored if you use the -viewer_binary_skip_info option. 1097 1098 If the type or size of newmat is not set before a call to MatLoad, PETSc 1099 sets the default matrix type AIJ and sets the local and global sizes. 1100 If type and/or size is already set, then the same are used. 1101 1102 In parallel, each processor can load a subset of rows (or the 1103 entire matrix). This routine is especially useful when a large 1104 matrix is stored on disk and only part of it is desired on each 1105 processor. For example, a parallel solver may access only some of 1106 the rows from each processor. The algorithm used here reads 1107 relatively small blocks of data rather than reading the entire 1108 matrix and then subsetting it. 1109 1110 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5. 1111 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(), 1112 or the sequence like 1113 $ PetscViewer v; 1114 $ PetscViewerCreate(PETSC_COMM_WORLD,&v); 1115 $ PetscViewerSetType(v,PETSCVIEWERBINARY); 1116 $ PetscViewerSetFromOptions(v); 1117 $ PetscViewerFileSetMode(v,FILE_MODE_READ); 1118 $ PetscViewerFileSetName(v,"datafile"); 1119 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option 1120 $ -viewer_type {binary,hdf5} 1121 1122 See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach, 1123 and src/mat/examples/tutorials/ex10.c with the second approach. 1124 1125 Notes about the PETSc binary format: 1126 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks 1127 is read onto rank 0 and then shipped to its destination rank, one after another. 1128 Multiple objects, both matrices and vectors, can be stored within the same file. 1129 Their PetscObject name is ignored; they are loaded in the order of their storage. 1130 1131 Most users should not need to know the details of the binary storage 1132 format, since MatLoad() and MatView() completely hide these details. 1133 But for anyone who's interested, the standard binary matrix storage 1134 format is 1135 1136 $ int MAT_FILE_CLASSID 1137 $ int number of rows 1138 $ int number of columns 1139 $ int total number of nonzeros 1140 $ int *number nonzeros in each row 1141 $ int *column indices of all nonzeros (starting index is zero) 1142 $ PetscScalar *values of all nonzeros 1143 1144 PETSc automatically does the byte swapping for 1145 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1146 linux, Windows and the paragon; thus if you write your own binary 1147 read/write routines you have to swap the bytes; see PetscBinaryRead() 1148 and PetscBinaryWrite() to see how this may be done. 1149 1150 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1151 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used. 1152 Each processor's chunk is loaded independently by its owning rank. 1153 Multiple objects, both matrices and vectors, can be stored within the same file. 1154 They are looked up by their PetscObject name. 1155 1156 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1157 by default the same structure and naming of the AIJ arrays and column count 1158 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1159 $ save example.mat A b -v7.3 1160 can be directly read by this routine (see Reference 1 for details). 1161 Note that depending on your MATLAB version, this format might be a default, 1162 otherwise you can set it as default in Preferences. 1163 1164 Unless -nocompression flag is used to save the file in MATLAB, 1165 PETSc must be configured with ZLIB package. 1166 1167 See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c 1168 1169 Current HDF5 (MAT-File) limitations: 1170 This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices. 1171 1172 Corresponding MatView() is not yet implemented. 1173 1174 The loaded matrix is actually a transpose of the original one in MATLAB, 1175 unless you push PETSC_VIEWER_HDF5_MAT format (see examples above). 1176 With this format, matrix is automatically transposed by PETSc, 1177 unless the matrix is marked as SPD or symmetric 1178 (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC). 1179 1180 References: 1181 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1182 1183 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad() 1184 1185 @*/ 1186 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer) 1187 { 1188 PetscErrorCode ierr; 1189 PetscBool flg; 1190 1191 PetscFunctionBegin; 1192 PetscValidHeaderSpecific(newmat,MAT_CLASSID,1); 1193 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1194 1195 if (!((PetscObject)newmat)->type_name) { 1196 ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 1197 } 1198 1199 flg = PETSC_FALSE; 1200 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr); 1201 if (flg) { 1202 ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 1203 ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); 1204 } 1205 flg = PETSC_FALSE; 1206 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr); 1207 if (flg) { 1208 ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 1209 } 1210 1211 if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type"); 1212 ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1213 ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr); 1214 ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1215 PetscFunctionReturn(0); 1216 } 1217 1218 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1219 { 1220 PetscErrorCode ierr; 1221 Mat_Redundant *redund = *redundant; 1222 PetscInt i; 1223 1224 PetscFunctionBegin; 1225 if (redund){ 1226 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1227 ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr); 1228 ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr); 1229 ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr); 1230 } else { 1231 ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr); 1232 ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr); 1233 ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr); 1234 for (i=0; i<redund->nrecvs; i++) { 1235 ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr); 1236 ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr); 1237 } 1238 ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr); 1239 } 1240 1241 if (redund->subcomm) { 1242 ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr); 1243 } 1244 ierr = PetscFree(redund);CHKERRQ(ierr); 1245 } 1246 PetscFunctionReturn(0); 1247 } 1248 1249 /*@ 1250 MatDestroy - Frees space taken by a matrix. 1251 1252 Collective on Mat 1253 1254 Input Parameter: 1255 . A - the matrix 1256 1257 Level: beginner 1258 1259 @*/ 1260 PetscErrorCode MatDestroy(Mat *A) 1261 { 1262 PetscErrorCode ierr; 1263 1264 PetscFunctionBegin; 1265 if (!*A) PetscFunctionReturn(0); 1266 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1267 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1268 1269 /* if memory was published with SAWs then destroy it */ 1270 ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr); 1271 if ((*A)->ops->destroy) { 1272 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr); 1273 } 1274 1275 ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr); 1276 ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr); 1277 ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr); 1278 ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr); 1279 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr); 1280 ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr); 1281 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr); 1282 ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr); 1283 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr); 1284 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr); 1285 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr); 1286 PetscFunctionReturn(0); 1287 } 1288 1289 /*@C 1290 MatSetValues - Inserts or adds a block of values into a matrix. 1291 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1292 MUST be called after all calls to MatSetValues() have been completed. 1293 1294 Not Collective 1295 1296 Input Parameters: 1297 + mat - the matrix 1298 . v - a logically two-dimensional array of values 1299 . m, idxm - the number of rows and their global indices 1300 . n, idxn - the number of columns and their global indices 1301 - addv - either ADD_VALUES or INSERT_VALUES, where 1302 ADD_VALUES adds values to any existing entries, and 1303 INSERT_VALUES replaces existing entries with new values 1304 1305 Notes: 1306 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1307 MatSetUp() before using this routine 1308 1309 By default the values, v, are row-oriented. See MatSetOption() for other options. 1310 1311 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1312 options cannot be mixed without intervening calls to the assembly 1313 routines. 1314 1315 MatSetValues() uses 0-based row and column numbers in Fortran 1316 as well as in C. 1317 1318 Negative indices may be passed in idxm and idxn, these rows and columns are 1319 simply ignored. This allows easily inserting element stiffness matrices 1320 with homogeneous Dirchlet boundary conditions that you don't want represented 1321 in the matrix. 1322 1323 Efficiency Alert: 1324 The routine MatSetValuesBlocked() may offer much better efficiency 1325 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1326 1327 Level: beginner 1328 1329 Developer Notes: 1330 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1331 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1332 1333 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1334 InsertMode, INSERT_VALUES, ADD_VALUES 1335 @*/ 1336 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1337 { 1338 PetscErrorCode ierr; 1339 #if defined(PETSC_USE_DEBUG) 1340 PetscInt i,j; 1341 #endif 1342 1343 PetscFunctionBeginHot; 1344 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1345 PetscValidType(mat,1); 1346 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1347 PetscValidIntPointer(idxm,3); 1348 PetscValidIntPointer(idxn,5); 1349 MatCheckPreallocated(mat,1); 1350 1351 if (mat->insertmode == NOT_SET_VALUES) { 1352 mat->insertmode = addv; 1353 } 1354 #if defined(PETSC_USE_DEBUG) 1355 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1356 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1357 if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1358 1359 for (i=0; i<m; i++) { 1360 for (j=0; j<n; j++) { 1361 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1362 #if defined(PETSC_USE_COMPLEX) 1363 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]); 1364 #else 1365 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]); 1366 #endif 1367 } 1368 } 1369 #endif 1370 1371 if (mat->assembled) { 1372 mat->was_assembled = PETSC_TRUE; 1373 mat->assembled = PETSC_FALSE; 1374 } 1375 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1376 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1377 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1378 PetscFunctionReturn(0); 1379 } 1380 1381 1382 /*@ 1383 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1384 values into a matrix 1385 1386 Not Collective 1387 1388 Input Parameters: 1389 + mat - the matrix 1390 . row - the (block) row to set 1391 - v - a logically two-dimensional array of values 1392 1393 Notes: 1394 By the values, v, are column-oriented (for the block version) and sorted 1395 1396 All the nonzeros in the row must be provided 1397 1398 The matrix must have previously had its column indices set 1399 1400 The row must belong to this process 1401 1402 Level: intermediate 1403 1404 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1405 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1406 @*/ 1407 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1408 { 1409 PetscErrorCode ierr; 1410 PetscInt globalrow; 1411 1412 PetscFunctionBegin; 1413 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1414 PetscValidType(mat,1); 1415 PetscValidScalarPointer(v,2); 1416 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr); 1417 ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr); 1418 PetscFunctionReturn(0); 1419 } 1420 1421 /*@ 1422 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1423 values into a matrix 1424 1425 Not Collective 1426 1427 Input Parameters: 1428 + mat - the matrix 1429 . row - the (block) row to set 1430 - 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 1431 1432 Notes: 1433 The values, v, are column-oriented for the block version. 1434 1435 All the nonzeros in the row must be provided 1436 1437 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1438 1439 The row must belong to this process 1440 1441 Level: advanced 1442 1443 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1444 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1445 @*/ 1446 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1447 { 1448 PetscErrorCode ierr; 1449 1450 PetscFunctionBeginHot; 1451 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1452 PetscValidType(mat,1); 1453 MatCheckPreallocated(mat,1); 1454 PetscValidScalarPointer(v,2); 1455 #if defined(PETSC_USE_DEBUG) 1456 if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1457 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1458 #endif 1459 mat->insertmode = INSERT_VALUES; 1460 1461 if (mat->assembled) { 1462 mat->was_assembled = PETSC_TRUE; 1463 mat->assembled = PETSC_FALSE; 1464 } 1465 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1466 if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1467 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr); 1468 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1469 PetscFunctionReturn(0); 1470 } 1471 1472 /*@ 1473 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1474 Using structured grid indexing 1475 1476 Not Collective 1477 1478 Input Parameters: 1479 + mat - the matrix 1480 . m - number of rows being entered 1481 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1482 . n - number of columns being entered 1483 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1484 . v - a logically two-dimensional array of values 1485 - addv - either ADD_VALUES or INSERT_VALUES, where 1486 ADD_VALUES adds values to any existing entries, and 1487 INSERT_VALUES replaces existing entries with new values 1488 1489 Notes: 1490 By default the values, v, are row-oriented. See MatSetOption() for other options. 1491 1492 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1493 options cannot be mixed without intervening calls to the assembly 1494 routines. 1495 1496 The grid coordinates are across the entire grid, not just the local portion 1497 1498 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1499 as well as in C. 1500 1501 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1502 1503 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1504 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1505 1506 The columns and rows in the stencil passed in MUST be contained within the 1507 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1508 if you create a DMDA with an overlap of one grid level and on a particular process its first 1509 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1510 first i index you can use in your column and row indices in MatSetStencil() is 5. 1511 1512 In Fortran idxm and idxn should be declared as 1513 $ MatStencil idxm(4,m),idxn(4,n) 1514 and the values inserted using 1515 $ idxm(MatStencil_i,1) = i 1516 $ idxm(MatStencil_j,1) = j 1517 $ idxm(MatStencil_k,1) = k 1518 $ idxm(MatStencil_c,1) = c 1519 etc 1520 1521 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1522 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1523 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1524 DM_BOUNDARY_PERIODIC boundary type. 1525 1526 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 1527 a single value per point) you can skip filling those indices. 1528 1529 Inspired by the structured grid interface to the HYPRE package 1530 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1531 1532 Efficiency Alert: 1533 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1534 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1535 1536 Level: beginner 1537 1538 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1539 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1540 @*/ 1541 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1542 { 1543 PetscErrorCode ierr; 1544 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1545 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1546 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1547 1548 PetscFunctionBegin; 1549 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1550 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1551 PetscValidType(mat,1); 1552 PetscValidIntPointer(idxm,3); 1553 PetscValidIntPointer(idxn,5); 1554 1555 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1556 jdxm = buf; jdxn = buf+m; 1557 } else { 1558 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1559 jdxm = bufm; jdxn = bufn; 1560 } 1561 for (i=0; i<m; i++) { 1562 for (j=0; j<3-sdim; j++) dxm++; 1563 tmp = *dxm++ - starts[0]; 1564 for (j=0; j<dim-1; j++) { 1565 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1566 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1567 } 1568 if (mat->stencil.noc) dxm++; 1569 jdxm[i] = tmp; 1570 } 1571 for (i=0; i<n; i++) { 1572 for (j=0; j<3-sdim; j++) dxn++; 1573 tmp = *dxn++ - starts[0]; 1574 for (j=0; j<dim-1; j++) { 1575 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1576 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1577 } 1578 if (mat->stencil.noc) dxn++; 1579 jdxn[i] = tmp; 1580 } 1581 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1582 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1583 PetscFunctionReturn(0); 1584 } 1585 1586 /*@ 1587 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1588 Using structured grid indexing 1589 1590 Not Collective 1591 1592 Input Parameters: 1593 + mat - the matrix 1594 . m - number of rows being entered 1595 . idxm - grid coordinates for matrix rows being entered 1596 . n - number of columns being entered 1597 . idxn - grid coordinates for matrix columns being entered 1598 . v - a logically two-dimensional array of values 1599 - addv - either ADD_VALUES or INSERT_VALUES, where 1600 ADD_VALUES adds values to any existing entries, and 1601 INSERT_VALUES replaces existing entries with new values 1602 1603 Notes: 1604 By default the values, v, are row-oriented and unsorted. 1605 See MatSetOption() for other options. 1606 1607 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1608 options cannot be mixed without intervening calls to the assembly 1609 routines. 1610 1611 The grid coordinates are across the entire grid, not just the local portion 1612 1613 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1614 as well as in C. 1615 1616 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1617 1618 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1619 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1620 1621 The columns and rows in the stencil passed in MUST be contained within the 1622 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1623 if you create a DMDA with an overlap of one grid level and on a particular process its first 1624 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1625 first i index you can use in your column and row indices in MatSetStencil() is 5. 1626 1627 In Fortran idxm and idxn should be declared as 1628 $ MatStencil idxm(4,m),idxn(4,n) 1629 and the values inserted using 1630 $ idxm(MatStencil_i,1) = i 1631 $ idxm(MatStencil_j,1) = j 1632 $ idxm(MatStencil_k,1) = k 1633 etc 1634 1635 Negative indices may be passed in idxm and idxn, these rows and columns are 1636 simply ignored. This allows easily inserting element stiffness matrices 1637 with homogeneous Dirchlet boundary conditions that you don't want represented 1638 in the matrix. 1639 1640 Inspired by the structured grid interface to the HYPRE package 1641 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1642 1643 Level: beginner 1644 1645 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1646 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1647 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1648 @*/ 1649 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1650 { 1651 PetscErrorCode ierr; 1652 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1653 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1654 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1655 1656 PetscFunctionBegin; 1657 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1658 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1659 PetscValidType(mat,1); 1660 PetscValidIntPointer(idxm,3); 1661 PetscValidIntPointer(idxn,5); 1662 PetscValidScalarPointer(v,6); 1663 1664 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1665 jdxm = buf; jdxn = buf+m; 1666 } else { 1667 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1668 jdxm = bufm; jdxn = bufn; 1669 } 1670 for (i=0; i<m; i++) { 1671 for (j=0; j<3-sdim; j++) dxm++; 1672 tmp = *dxm++ - starts[0]; 1673 for (j=0; j<sdim-1; j++) { 1674 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1675 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1676 } 1677 dxm++; 1678 jdxm[i] = tmp; 1679 } 1680 for (i=0; i<n; i++) { 1681 for (j=0; j<3-sdim; j++) dxn++; 1682 tmp = *dxn++ - starts[0]; 1683 for (j=0; j<sdim-1; j++) { 1684 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1685 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1686 } 1687 dxn++; 1688 jdxn[i] = tmp; 1689 } 1690 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1691 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1692 PetscFunctionReturn(0); 1693 } 1694 1695 /*@ 1696 MatSetStencil - Sets the grid information for setting values into a matrix via 1697 MatSetValuesStencil() 1698 1699 Not Collective 1700 1701 Input Parameters: 1702 + mat - the matrix 1703 . dim - dimension of the grid 1, 2, or 3 1704 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1705 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1706 - dof - number of degrees of freedom per node 1707 1708 1709 Inspired by the structured grid interface to the HYPRE package 1710 (www.llnl.gov/CASC/hyper) 1711 1712 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1713 user. 1714 1715 Level: beginner 1716 1717 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1718 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1719 @*/ 1720 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1721 { 1722 PetscInt i; 1723 1724 PetscFunctionBegin; 1725 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1726 PetscValidIntPointer(dims,3); 1727 PetscValidIntPointer(starts,4); 1728 1729 mat->stencil.dim = dim + (dof > 1); 1730 for (i=0; i<dim; i++) { 1731 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1732 mat->stencil.starts[i] = starts[dim-i-1]; 1733 } 1734 mat->stencil.dims[dim] = dof; 1735 mat->stencil.starts[dim] = 0; 1736 mat->stencil.noc = (PetscBool)(dof == 1); 1737 PetscFunctionReturn(0); 1738 } 1739 1740 /*@C 1741 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1742 1743 Not Collective 1744 1745 Input Parameters: 1746 + mat - the matrix 1747 . v - a logically two-dimensional array of values 1748 . m, idxm - the number of block rows and their global block indices 1749 . n, idxn - the number of block columns and their global block indices 1750 - addv - either ADD_VALUES or INSERT_VALUES, where 1751 ADD_VALUES adds values to any existing entries, and 1752 INSERT_VALUES replaces existing entries with new values 1753 1754 Notes: 1755 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1756 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1757 1758 The m and n count the NUMBER of blocks in the row direction and column direction, 1759 NOT the total number of rows/columns; for example, if the block size is 2 and 1760 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1761 The values in idxm would be 1 2; that is the first index for each block divided by 1762 the block size. 1763 1764 Note that you must call MatSetBlockSize() when constructing this matrix (before 1765 preallocating it). 1766 1767 By default the values, v, are row-oriented, so the layout of 1768 v is the same as for MatSetValues(). See MatSetOption() for other options. 1769 1770 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1771 options cannot be mixed without intervening calls to the assembly 1772 routines. 1773 1774 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1775 as well as in C. 1776 1777 Negative indices may be passed in idxm and idxn, these rows and columns are 1778 simply ignored. This allows easily inserting element stiffness matrices 1779 with homogeneous Dirchlet boundary conditions that you don't want represented 1780 in the matrix. 1781 1782 Each time an entry is set within a sparse matrix via MatSetValues(), 1783 internal searching must be done to determine where to place the 1784 data in the matrix storage space. By instead inserting blocks of 1785 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1786 reduced. 1787 1788 Example: 1789 $ Suppose m=n=2 and block size(bs) = 2 The array is 1790 $ 1791 $ 1 2 | 3 4 1792 $ 5 6 | 7 8 1793 $ - - - | - - - 1794 $ 9 10 | 11 12 1795 $ 13 14 | 15 16 1796 $ 1797 $ v[] should be passed in like 1798 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1799 $ 1800 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1801 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1802 1803 Level: intermediate 1804 1805 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1806 @*/ 1807 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1808 { 1809 PetscErrorCode ierr; 1810 1811 PetscFunctionBeginHot; 1812 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1813 PetscValidType(mat,1); 1814 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1815 PetscValidIntPointer(idxm,3); 1816 PetscValidIntPointer(idxn,5); 1817 PetscValidScalarPointer(v,6); 1818 MatCheckPreallocated(mat,1); 1819 if (mat->insertmode == NOT_SET_VALUES) { 1820 mat->insertmode = addv; 1821 } 1822 #if defined(PETSC_USE_DEBUG) 1823 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1824 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1825 if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1826 #endif 1827 1828 if (mat->assembled) { 1829 mat->was_assembled = PETSC_TRUE; 1830 mat->assembled = PETSC_FALSE; 1831 } 1832 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1833 if (mat->ops->setvaluesblocked) { 1834 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1835 } else { 1836 PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn; 1837 PetscInt i,j,bs,cbs; 1838 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr); 1839 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1840 iidxm = buf; iidxn = buf + m*bs; 1841 } else { 1842 ierr = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr); 1843 iidxm = bufr; iidxn = bufc; 1844 } 1845 for (i=0; i<m; i++) { 1846 for (j=0; j<bs; j++) { 1847 iidxm[i*bs+j] = bs*idxm[i] + j; 1848 } 1849 } 1850 for (i=0; i<n; i++) { 1851 for (j=0; j<cbs; j++) { 1852 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1853 } 1854 } 1855 ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr); 1856 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1857 } 1858 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1859 PetscFunctionReturn(0); 1860 } 1861 1862 /*@ 1863 MatGetValues - Gets a block of values from a matrix. 1864 1865 Not Collective; currently only returns a local block 1866 1867 Input Parameters: 1868 + mat - the matrix 1869 . v - a logically two-dimensional array for storing the values 1870 . m, idxm - the number of rows and their global indices 1871 - n, idxn - the number of columns and their global indices 1872 1873 Notes: 1874 The user must allocate space (m*n PetscScalars) for the values, v. 1875 The values, v, are then returned in a row-oriented format, 1876 analogous to that used by default in MatSetValues(). 1877 1878 MatGetValues() uses 0-based row and column numbers in 1879 Fortran as well as in C. 1880 1881 MatGetValues() requires that the matrix has been assembled 1882 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1883 MatSetValues() and MatGetValues() CANNOT be made in succession 1884 without intermediate matrix assembly. 1885 1886 Negative row or column indices will be ignored and those locations in v[] will be 1887 left unchanged. 1888 1889 Level: advanced 1890 1891 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues() 1892 @*/ 1893 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1894 { 1895 PetscErrorCode ierr; 1896 1897 PetscFunctionBegin; 1898 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1899 PetscValidType(mat,1); 1900 if (!m || !n) PetscFunctionReturn(0); 1901 PetscValidIntPointer(idxm,3); 1902 PetscValidIntPointer(idxn,5); 1903 PetscValidScalarPointer(v,6); 1904 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1905 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1906 if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1907 MatCheckPreallocated(mat,1); 1908 1909 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1910 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 1911 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1912 PetscFunctionReturn(0); 1913 } 1914 1915 /*@ 1916 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 1917 the same size. Currently, this can only be called once and creates the given matrix. 1918 1919 Not Collective 1920 1921 Input Parameters: 1922 + mat - the matrix 1923 . nb - the number of blocks 1924 . bs - the number of rows (and columns) in each block 1925 . rows - a concatenation of the rows for each block 1926 - v - a concatenation of logically two-dimensional arrays of values 1927 1928 Notes: 1929 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 1930 1931 Level: advanced 1932 1933 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1934 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1935 @*/ 1936 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 1937 { 1938 PetscErrorCode ierr; 1939 1940 PetscFunctionBegin; 1941 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1942 PetscValidType(mat,1); 1943 PetscValidScalarPointer(rows,4); 1944 PetscValidScalarPointer(v,5); 1945 #if defined(PETSC_USE_DEBUG) 1946 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1947 #endif 1948 1949 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1950 if (mat->ops->setvaluesbatch) { 1951 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr); 1952 } else { 1953 PetscInt b; 1954 for (b = 0; b < nb; ++b) { 1955 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr); 1956 } 1957 } 1958 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1959 PetscFunctionReturn(0); 1960 } 1961 1962 /*@ 1963 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 1964 the routine MatSetValuesLocal() to allow users to insert matrix entries 1965 using a local (per-processor) numbering. 1966 1967 Not Collective 1968 1969 Input Parameters: 1970 + x - the matrix 1971 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 1972 - cmapping - column mapping 1973 1974 Level: intermediate 1975 1976 1977 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal() 1978 @*/ 1979 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 1980 { 1981 PetscErrorCode ierr; 1982 1983 PetscFunctionBegin; 1984 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 1985 PetscValidType(x,1); 1986 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 1987 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 1988 1989 if (x->ops->setlocaltoglobalmapping) { 1990 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr); 1991 } else { 1992 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr); 1993 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr); 1994 } 1995 PetscFunctionReturn(0); 1996 } 1997 1998 1999 /*@ 2000 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2001 2002 Not Collective 2003 2004 Input Parameters: 2005 . A - the matrix 2006 2007 Output Parameters: 2008 + rmapping - row mapping 2009 - cmapping - column mapping 2010 2011 Level: advanced 2012 2013 2014 .seealso: MatSetValuesLocal() 2015 @*/ 2016 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2017 { 2018 PetscFunctionBegin; 2019 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2020 PetscValidType(A,1); 2021 if (rmapping) PetscValidPointer(rmapping,2); 2022 if (cmapping) PetscValidPointer(cmapping,3); 2023 if (rmapping) *rmapping = A->rmap->mapping; 2024 if (cmapping) *cmapping = A->cmap->mapping; 2025 PetscFunctionReturn(0); 2026 } 2027 2028 /*@ 2029 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2030 2031 Not Collective 2032 2033 Input Parameters: 2034 . A - the matrix 2035 2036 Output Parameters: 2037 + rmap - row layout 2038 - cmap - column layout 2039 2040 Level: advanced 2041 2042 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping() 2043 @*/ 2044 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2045 { 2046 PetscFunctionBegin; 2047 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2048 PetscValidType(A,1); 2049 if (rmap) PetscValidPointer(rmap,2); 2050 if (cmap) PetscValidPointer(cmap,3); 2051 if (rmap) *rmap = A->rmap; 2052 if (cmap) *cmap = A->cmap; 2053 PetscFunctionReturn(0); 2054 } 2055 2056 /*@C 2057 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2058 using a local ordering of the nodes. 2059 2060 Not Collective 2061 2062 Input Parameters: 2063 + mat - the matrix 2064 . nrow, irow - number of rows and their local indices 2065 . ncol, icol - number of columns and their local indices 2066 . y - a logically two-dimensional array of values 2067 - addv - either INSERT_VALUES or ADD_VALUES, where 2068 ADD_VALUES adds values to any existing entries, and 2069 INSERT_VALUES replaces existing entries with new values 2070 2071 Notes: 2072 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2073 MatSetUp() before using this routine 2074 2075 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2076 2077 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2078 options cannot be mixed without intervening calls to the assembly 2079 routines. 2080 2081 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2082 MUST be called after all calls to MatSetValuesLocal() have been completed. 2083 2084 Level: intermediate 2085 2086 Developer Notes: 2087 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2088 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2089 2090 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 2091 MatSetValueLocal() 2092 @*/ 2093 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2094 { 2095 PetscErrorCode ierr; 2096 2097 PetscFunctionBeginHot; 2098 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2099 PetscValidType(mat,1); 2100 MatCheckPreallocated(mat,1); 2101 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2102 PetscValidIntPointer(irow,3); 2103 PetscValidIntPointer(icol,5); 2104 if (mat->insertmode == NOT_SET_VALUES) { 2105 mat->insertmode = addv; 2106 } 2107 #if defined(PETSC_USE_DEBUG) 2108 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2109 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2110 if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2111 #endif 2112 2113 if (mat->assembled) { 2114 mat->was_assembled = PETSC_TRUE; 2115 mat->assembled = PETSC_FALSE; 2116 } 2117 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2118 if (mat->ops->setvalueslocal) { 2119 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2120 } else { 2121 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2122 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2123 irowm = buf; icolm = buf+nrow; 2124 } else { 2125 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2126 irowm = bufr; icolm = bufc; 2127 } 2128 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2129 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2130 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2131 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2132 } 2133 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2134 PetscFunctionReturn(0); 2135 } 2136 2137 /*@C 2138 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2139 using a local ordering of the nodes a block at a time. 2140 2141 Not Collective 2142 2143 Input Parameters: 2144 + x - the matrix 2145 . nrow, irow - number of rows and their local indices 2146 . ncol, icol - number of columns and their local indices 2147 . y - a logically two-dimensional array of values 2148 - addv - either INSERT_VALUES or ADD_VALUES, where 2149 ADD_VALUES adds values to any existing entries, and 2150 INSERT_VALUES replaces existing entries with new values 2151 2152 Notes: 2153 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2154 MatSetUp() before using this routine 2155 2156 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2157 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2158 2159 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2160 options cannot be mixed without intervening calls to the assembly 2161 routines. 2162 2163 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2164 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2165 2166 Level: intermediate 2167 2168 Developer Notes: 2169 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2170 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2171 2172 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(), 2173 MatSetValuesLocal(), MatSetValuesBlocked() 2174 @*/ 2175 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2176 { 2177 PetscErrorCode ierr; 2178 2179 PetscFunctionBeginHot; 2180 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2181 PetscValidType(mat,1); 2182 MatCheckPreallocated(mat,1); 2183 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2184 PetscValidIntPointer(irow,3); 2185 PetscValidIntPointer(icol,5); 2186 PetscValidScalarPointer(y,6); 2187 if (mat->insertmode == NOT_SET_VALUES) { 2188 mat->insertmode = addv; 2189 } 2190 #if defined(PETSC_USE_DEBUG) 2191 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2192 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2193 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); 2194 #endif 2195 2196 if (mat->assembled) { 2197 mat->was_assembled = PETSC_TRUE; 2198 mat->assembled = PETSC_FALSE; 2199 } 2200 #if defined(PETSC_USE_DEBUG) 2201 /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2202 if (mat->rmap->mapping) { 2203 PetscInt irbs, rbs; 2204 ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr); 2205 ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr); 2206 if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs); 2207 } 2208 if (mat->cmap->mapping) { 2209 PetscInt icbs, cbs; 2210 ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr); 2211 ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr); 2212 if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs); 2213 } 2214 #endif 2215 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2216 if (mat->ops->setvaluesblockedlocal) { 2217 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2218 } else { 2219 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2220 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2221 irowm = buf; icolm = buf + nrow; 2222 } else { 2223 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2224 irowm = bufr; icolm = bufc; 2225 } 2226 ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2227 ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2228 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2229 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2230 } 2231 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2232 PetscFunctionReturn(0); 2233 } 2234 2235 /*@ 2236 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2237 2238 Collective on Mat 2239 2240 Input Parameters: 2241 + mat - the matrix 2242 - x - the vector to be multiplied 2243 2244 Output Parameters: 2245 . y - the result 2246 2247 Notes: 2248 The vectors x and y cannot be the same. I.e., one cannot 2249 call MatMult(A,y,y). 2250 2251 Level: developer 2252 2253 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2254 @*/ 2255 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2256 { 2257 PetscErrorCode ierr; 2258 2259 PetscFunctionBegin; 2260 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2261 PetscValidType(mat,1); 2262 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2263 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2264 2265 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2266 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2267 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2268 MatCheckPreallocated(mat,1); 2269 2270 if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2271 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr); 2272 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2273 PetscFunctionReturn(0); 2274 } 2275 2276 /* --------------------------------------------------------*/ 2277 /*@ 2278 MatMult - Computes the matrix-vector product, y = Ax. 2279 2280 Neighbor-wise Collective on Mat 2281 2282 Input Parameters: 2283 + mat - the matrix 2284 - x - the vector to be multiplied 2285 2286 Output Parameters: 2287 . y - the result 2288 2289 Notes: 2290 The vectors x and y cannot be the same. I.e., one cannot 2291 call MatMult(A,y,y). 2292 2293 Level: beginner 2294 2295 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2296 @*/ 2297 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2298 { 2299 PetscErrorCode ierr; 2300 2301 PetscFunctionBegin; 2302 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2303 PetscValidType(mat,1); 2304 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2305 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2306 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2307 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2308 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2309 #if !defined(PETSC_HAVE_CONSTRAINTS) 2310 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); 2311 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); 2312 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); 2313 #endif 2314 ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr); 2315 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2316 MatCheckPreallocated(mat,1); 2317 2318 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2319 if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2320 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2321 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2322 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2323 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2324 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2325 PetscFunctionReturn(0); 2326 } 2327 2328 /*@ 2329 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2330 2331 Neighbor-wise Collective on Mat 2332 2333 Input Parameters: 2334 + mat - the matrix 2335 - x - the vector to be multiplied 2336 2337 Output Parameters: 2338 . y - the result 2339 2340 Notes: 2341 The vectors x and y cannot be the same. I.e., one cannot 2342 call MatMultTranspose(A,y,y). 2343 2344 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2345 use MatMultHermitianTranspose() 2346 2347 Level: beginner 2348 2349 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2350 @*/ 2351 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2352 { 2353 PetscErrorCode ierr; 2354 2355 PetscFunctionBegin; 2356 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2357 PetscValidType(mat,1); 2358 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2359 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2360 2361 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2362 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2363 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2364 #if !defined(PETSC_HAVE_CONSTRAINTS) 2365 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); 2366 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); 2367 #endif 2368 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2369 MatCheckPreallocated(mat,1); 2370 2371 if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined"); 2372 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2373 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2374 ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr); 2375 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2376 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2377 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2378 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2379 PetscFunctionReturn(0); 2380 } 2381 2382 /*@ 2383 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2384 2385 Neighbor-wise Collective on Mat 2386 2387 Input Parameters: 2388 + mat - the matrix 2389 - x - the vector to be multilplied 2390 2391 Output Parameters: 2392 . y - the result 2393 2394 Notes: 2395 The vectors x and y cannot be the same. I.e., one cannot 2396 call MatMultHermitianTranspose(A,y,y). 2397 2398 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2399 2400 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2401 2402 Level: beginner 2403 2404 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2405 @*/ 2406 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2407 { 2408 PetscErrorCode ierr; 2409 Vec w; 2410 2411 PetscFunctionBegin; 2412 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2413 PetscValidType(mat,1); 2414 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2415 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2416 2417 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2418 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2419 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2420 #if !defined(PETSC_HAVE_CONSTRAINTS) 2421 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); 2422 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); 2423 #endif 2424 MatCheckPreallocated(mat,1); 2425 2426 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2427 if (mat->ops->multhermitiantranspose) { 2428 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2429 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr); 2430 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2431 } else { 2432 ierr = VecDuplicate(x,&w);CHKERRQ(ierr); 2433 ierr = VecCopy(x,w);CHKERRQ(ierr); 2434 ierr = VecConjugate(w);CHKERRQ(ierr); 2435 ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr); 2436 ierr = VecDestroy(&w);CHKERRQ(ierr); 2437 ierr = VecConjugate(y);CHKERRQ(ierr); 2438 } 2439 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2440 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2441 PetscFunctionReturn(0); 2442 } 2443 2444 /*@ 2445 MatMultAdd - Computes v3 = v2 + A * v1. 2446 2447 Neighbor-wise Collective on Mat 2448 2449 Input Parameters: 2450 + mat - the matrix 2451 - v1, v2 - the vectors 2452 2453 Output Parameters: 2454 . v3 - the result 2455 2456 Notes: 2457 The vectors v1 and v3 cannot be the same. I.e., one cannot 2458 call MatMultAdd(A,v1,v2,v1). 2459 2460 Level: beginner 2461 2462 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2463 @*/ 2464 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2465 { 2466 PetscErrorCode ierr; 2467 2468 PetscFunctionBegin; 2469 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2470 PetscValidType(mat,1); 2471 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2472 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2473 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2474 2475 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2476 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2477 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); 2478 /* 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); 2479 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); */ 2480 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); 2481 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); 2482 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2483 MatCheckPreallocated(mat,1); 2484 2485 if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name); 2486 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2487 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2488 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2489 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2490 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2491 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2492 PetscFunctionReturn(0); 2493 } 2494 2495 /*@ 2496 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2497 2498 Neighbor-wise Collective on Mat 2499 2500 Input Parameters: 2501 + mat - the matrix 2502 - v1, v2 - the vectors 2503 2504 Output Parameters: 2505 . v3 - the result 2506 2507 Notes: 2508 The vectors v1 and v3 cannot be the same. I.e., one cannot 2509 call MatMultTransposeAdd(A,v1,v2,v1). 2510 2511 Level: beginner 2512 2513 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2514 @*/ 2515 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2516 { 2517 PetscErrorCode ierr; 2518 2519 PetscFunctionBegin; 2520 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2521 PetscValidType(mat,1); 2522 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2523 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2524 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2525 2526 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2527 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2528 if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2529 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2530 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); 2531 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); 2532 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); 2533 MatCheckPreallocated(mat,1); 2534 2535 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2536 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2537 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2538 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2539 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2540 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2541 PetscFunctionReturn(0); 2542 } 2543 2544 /*@ 2545 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2546 2547 Neighbor-wise Collective on Mat 2548 2549 Input Parameters: 2550 + mat - the matrix 2551 - v1, v2 - the vectors 2552 2553 Output Parameters: 2554 . v3 - the result 2555 2556 Notes: 2557 The vectors v1 and v3 cannot be the same. I.e., one cannot 2558 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2559 2560 Level: beginner 2561 2562 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2563 @*/ 2564 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2565 { 2566 PetscErrorCode ierr; 2567 2568 PetscFunctionBegin; 2569 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2570 PetscValidType(mat,1); 2571 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2572 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2573 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2574 2575 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2576 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2577 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2578 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); 2579 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); 2580 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); 2581 MatCheckPreallocated(mat,1); 2582 2583 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2584 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2585 if (mat->ops->multhermitiantransposeadd) { 2586 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2587 } else { 2588 Vec w,z; 2589 ierr = VecDuplicate(v1,&w);CHKERRQ(ierr); 2590 ierr = VecCopy(v1,w);CHKERRQ(ierr); 2591 ierr = VecConjugate(w);CHKERRQ(ierr); 2592 ierr = VecDuplicate(v3,&z);CHKERRQ(ierr); 2593 ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr); 2594 ierr = VecDestroy(&w);CHKERRQ(ierr); 2595 ierr = VecConjugate(z);CHKERRQ(ierr); 2596 if (v2 != v3) { 2597 ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr); 2598 } else { 2599 ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr); 2600 } 2601 ierr = VecDestroy(&z);CHKERRQ(ierr); 2602 } 2603 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2604 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2605 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2606 PetscFunctionReturn(0); 2607 } 2608 2609 /*@ 2610 MatMultConstrained - The inner multiplication routine for a 2611 constrained matrix P^T A P. 2612 2613 Neighbor-wise Collective on Mat 2614 2615 Input Parameters: 2616 + mat - the matrix 2617 - x - the vector to be multilplied 2618 2619 Output Parameters: 2620 . y - the result 2621 2622 Notes: 2623 The vectors x and y cannot be the same. I.e., one cannot 2624 call MatMult(A,y,y). 2625 2626 Level: beginner 2627 2628 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2629 @*/ 2630 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y) 2631 { 2632 PetscErrorCode ierr; 2633 2634 PetscFunctionBegin; 2635 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2636 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2637 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2638 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2639 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2640 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2641 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); 2642 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); 2643 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); 2644 2645 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2646 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2647 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr); 2648 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2649 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2650 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2651 PetscFunctionReturn(0); 2652 } 2653 2654 /*@ 2655 MatMultTransposeConstrained - The inner multiplication routine for a 2656 constrained matrix P^T A^T P. 2657 2658 Neighbor-wise Collective on Mat 2659 2660 Input Parameters: 2661 + mat - the matrix 2662 - x - the vector to be multilplied 2663 2664 Output Parameters: 2665 . y - the result 2666 2667 Notes: 2668 The vectors x and y cannot be the same. I.e., one cannot 2669 call MatMult(A,y,y). 2670 2671 Level: beginner 2672 2673 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2674 @*/ 2675 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 2676 { 2677 PetscErrorCode ierr; 2678 2679 PetscFunctionBegin; 2680 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2681 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2682 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2683 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2684 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2685 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2686 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); 2687 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); 2688 2689 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2690 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 2691 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2692 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2693 PetscFunctionReturn(0); 2694 } 2695 2696 /*@C 2697 MatGetFactorType - gets the type of factorization it is 2698 2699 Not Collective 2700 2701 Input Parameters: 2702 . mat - the matrix 2703 2704 Output Parameters: 2705 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2706 2707 Level: intermediate 2708 2709 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType() 2710 @*/ 2711 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2712 { 2713 PetscFunctionBegin; 2714 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2715 PetscValidType(mat,1); 2716 PetscValidPointer(t,2); 2717 *t = mat->factortype; 2718 PetscFunctionReturn(0); 2719 } 2720 2721 /*@C 2722 MatSetFactorType - sets the type of factorization it is 2723 2724 Logically Collective on Mat 2725 2726 Input Parameters: 2727 + mat - the matrix 2728 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2729 2730 Level: intermediate 2731 2732 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType() 2733 @*/ 2734 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2735 { 2736 PetscFunctionBegin; 2737 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2738 PetscValidType(mat,1); 2739 mat->factortype = t; 2740 PetscFunctionReturn(0); 2741 } 2742 2743 /* ------------------------------------------------------------*/ 2744 /*@C 2745 MatGetInfo - Returns information about matrix storage (number of 2746 nonzeros, memory, etc.). 2747 2748 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2749 2750 Input Parameters: 2751 . mat - the matrix 2752 2753 Output Parameters: 2754 + flag - flag indicating the type of parameters to be returned 2755 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2756 MAT_GLOBAL_SUM - sum over all processors) 2757 - info - matrix information context 2758 2759 Notes: 2760 The MatInfo context contains a variety of matrix data, including 2761 number of nonzeros allocated and used, number of mallocs during 2762 matrix assembly, etc. Additional information for factored matrices 2763 is provided (such as the fill ratio, number of mallocs during 2764 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2765 when using the runtime options 2766 $ -info -mat_view ::ascii_info 2767 2768 Example for C/C++ Users: 2769 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2770 data within the MatInfo context. For example, 2771 .vb 2772 MatInfo info; 2773 Mat A; 2774 double mal, nz_a, nz_u; 2775 2776 MatGetInfo(A,MAT_LOCAL,&info); 2777 mal = info.mallocs; 2778 nz_a = info.nz_allocated; 2779 .ve 2780 2781 Example for Fortran Users: 2782 Fortran users should declare info as a double precision 2783 array of dimension MAT_INFO_SIZE, and then extract the parameters 2784 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2785 a complete list of parameter names. 2786 .vb 2787 double precision info(MAT_INFO_SIZE) 2788 double precision mal, nz_a 2789 Mat A 2790 integer ierr 2791 2792 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2793 mal = info(MAT_INFO_MALLOCS) 2794 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2795 .ve 2796 2797 Level: intermediate 2798 2799 Developer Note: fortran interface is not autogenerated as the f90 2800 interface defintion cannot be generated correctly [due to MatInfo] 2801 2802 .seealso: MatStashGetInfo() 2803 2804 @*/ 2805 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2806 { 2807 PetscErrorCode ierr; 2808 2809 PetscFunctionBegin; 2810 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2811 PetscValidType(mat,1); 2812 PetscValidPointer(info,3); 2813 if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2814 MatCheckPreallocated(mat,1); 2815 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 2816 PetscFunctionReturn(0); 2817 } 2818 2819 /* 2820 This is used by external packages where it is not easy to get the info from the actual 2821 matrix factorization. 2822 */ 2823 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2824 { 2825 PetscErrorCode ierr; 2826 2827 PetscFunctionBegin; 2828 ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr); 2829 PetscFunctionReturn(0); 2830 } 2831 2832 /* ----------------------------------------------------------*/ 2833 2834 /*@C 2835 MatLUFactor - Performs in-place LU factorization of matrix. 2836 2837 Collective on Mat 2838 2839 Input Parameters: 2840 + mat - the matrix 2841 . row - row permutation 2842 . col - column permutation 2843 - info - options for factorization, includes 2844 $ fill - expected fill as ratio of original fill. 2845 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2846 $ Run with the option -info to determine an optimal value to use 2847 2848 Notes: 2849 Most users should employ the simplified KSP interface for linear solvers 2850 instead of working directly with matrix algebra routines such as this. 2851 See, e.g., KSPCreate(). 2852 2853 This changes the state of the matrix to a factored matrix; it cannot be used 2854 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2855 2856 Level: developer 2857 2858 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 2859 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 2860 2861 Developer Note: fortran interface is not autogenerated as the f90 2862 interface defintion cannot be generated correctly [due to MatFactorInfo] 2863 2864 @*/ 2865 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2866 { 2867 PetscErrorCode ierr; 2868 MatFactorInfo tinfo; 2869 2870 PetscFunctionBegin; 2871 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2872 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2873 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2874 if (info) PetscValidPointer(info,4); 2875 PetscValidType(mat,1); 2876 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2877 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2878 if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2879 MatCheckPreallocated(mat,1); 2880 if (!info) { 2881 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2882 info = &tinfo; 2883 } 2884 2885 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2886 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 2887 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2888 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2889 PetscFunctionReturn(0); 2890 } 2891 2892 /*@C 2893 MatILUFactor - Performs in-place ILU factorization of matrix. 2894 2895 Collective on Mat 2896 2897 Input Parameters: 2898 + mat - the matrix 2899 . row - row permutation 2900 . col - column permutation 2901 - info - structure containing 2902 $ levels - number of levels of fill. 2903 $ expected fill - as ratio of original fill. 2904 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2905 missing diagonal entries) 2906 2907 Notes: 2908 Probably really in-place only when level of fill is zero, otherwise allocates 2909 new space to store factored matrix and deletes previous memory. 2910 2911 Most users should employ the simplified KSP interface for linear solvers 2912 instead of working directly with matrix algebra routines such as this. 2913 See, e.g., KSPCreate(). 2914 2915 Level: developer 2916 2917 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 2918 2919 Developer Note: fortran interface is not autogenerated as the f90 2920 interface defintion cannot be generated correctly [due to MatFactorInfo] 2921 2922 @*/ 2923 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2924 { 2925 PetscErrorCode ierr; 2926 2927 PetscFunctionBegin; 2928 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2929 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2930 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2931 PetscValidPointer(info,4); 2932 PetscValidType(mat,1); 2933 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 2934 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2935 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2936 if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2937 MatCheckPreallocated(mat,1); 2938 2939 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2940 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 2941 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2942 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2943 PetscFunctionReturn(0); 2944 } 2945 2946 /*@C 2947 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 2948 Call this routine before calling MatLUFactorNumeric(). 2949 2950 Collective on Mat 2951 2952 Input Parameters: 2953 + fact - the factor matrix obtained with MatGetFactor() 2954 . mat - the matrix 2955 . row, col - row and column permutations 2956 - info - options for factorization, includes 2957 $ fill - expected fill as ratio of original fill. 2958 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2959 $ Run with the option -info to determine an optimal value to use 2960 2961 2962 Notes: 2963 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 2964 2965 Most users should employ the simplified KSP interface for linear solvers 2966 instead of working directly with matrix algebra routines such as this. 2967 See, e.g., KSPCreate(). 2968 2969 Level: developer 2970 2971 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize() 2972 2973 Developer Note: fortran interface is not autogenerated as the f90 2974 interface defintion cannot be generated correctly [due to MatFactorInfo] 2975 2976 @*/ 2977 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 2978 { 2979 PetscErrorCode ierr; 2980 MatFactorInfo tinfo; 2981 2982 PetscFunctionBegin; 2983 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2984 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2985 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2986 if (info) PetscValidPointer(info,4); 2987 PetscValidType(mat,1); 2988 PetscValidPointer(fact,5); 2989 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2990 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2991 if (!(fact)->ops->lufactorsymbolic) { 2992 MatSolverType spackage; 2993 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 2994 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage); 2995 } 2996 MatCheckPreallocated(mat,2); 2997 if (!info) { 2998 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2999 info = &tinfo; 3000 } 3001 3002 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3003 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 3004 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3005 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3006 PetscFunctionReturn(0); 3007 } 3008 3009 /*@C 3010 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3011 Call this routine after first calling MatLUFactorSymbolic(). 3012 3013 Collective on Mat 3014 3015 Input Parameters: 3016 + fact - the factor matrix obtained with MatGetFactor() 3017 . mat - the matrix 3018 - info - options for factorization 3019 3020 Notes: 3021 See MatLUFactor() for in-place factorization. See 3022 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3023 3024 Most users should employ the simplified KSP interface for linear solvers 3025 instead of working directly with matrix algebra routines such as this. 3026 See, e.g., KSPCreate(). 3027 3028 Level: developer 3029 3030 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 3031 3032 Developer Note: fortran interface is not autogenerated as the f90 3033 interface defintion cannot be generated correctly [due to MatFactorInfo] 3034 3035 @*/ 3036 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3037 { 3038 MatFactorInfo tinfo; 3039 PetscErrorCode ierr; 3040 3041 PetscFunctionBegin; 3042 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3043 PetscValidType(mat,1); 3044 PetscValidPointer(fact,2); 3045 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3046 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3047 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); 3048 3049 if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3050 MatCheckPreallocated(mat,2); 3051 if (!info) { 3052 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3053 info = &tinfo; 3054 } 3055 3056 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3057 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr); 3058 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3059 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3060 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3061 PetscFunctionReturn(0); 3062 } 3063 3064 /*@C 3065 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3066 symmetric matrix. 3067 3068 Collective on Mat 3069 3070 Input Parameters: 3071 + mat - the matrix 3072 . perm - row and column permutations 3073 - f - expected fill as ratio of original fill 3074 3075 Notes: 3076 See MatLUFactor() for the nonsymmetric case. See also 3077 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3078 3079 Most users should employ the simplified KSP interface for linear solvers 3080 instead of working directly with matrix algebra routines such as this. 3081 See, e.g., KSPCreate(). 3082 3083 Level: developer 3084 3085 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 3086 MatGetOrdering() 3087 3088 Developer Note: fortran interface is not autogenerated as the f90 3089 interface defintion cannot be generated correctly [due to MatFactorInfo] 3090 3091 @*/ 3092 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3093 { 3094 PetscErrorCode ierr; 3095 MatFactorInfo tinfo; 3096 3097 PetscFunctionBegin; 3098 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3099 PetscValidType(mat,1); 3100 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3101 if (info) PetscValidPointer(info,3); 3102 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3103 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3104 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3105 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); 3106 MatCheckPreallocated(mat,1); 3107 if (!info) { 3108 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3109 info = &tinfo; 3110 } 3111 3112 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3113 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr); 3114 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3115 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3116 PetscFunctionReturn(0); 3117 } 3118 3119 /*@C 3120 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3121 of a symmetric matrix. 3122 3123 Collective on Mat 3124 3125 Input Parameters: 3126 + fact - the factor matrix obtained with MatGetFactor() 3127 . mat - the matrix 3128 . perm - row and column permutations 3129 - info - options for factorization, includes 3130 $ fill - expected fill as ratio of original fill. 3131 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3132 $ Run with the option -info to determine an optimal value to use 3133 3134 Notes: 3135 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3136 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3137 3138 Most users should employ the simplified KSP interface for linear solvers 3139 instead of working directly with matrix algebra routines such as this. 3140 See, e.g., KSPCreate(). 3141 3142 Level: developer 3143 3144 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 3145 MatGetOrdering() 3146 3147 Developer Note: fortran interface is not autogenerated as the f90 3148 interface defintion cannot be generated correctly [due to MatFactorInfo] 3149 3150 @*/ 3151 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3152 { 3153 PetscErrorCode ierr; 3154 MatFactorInfo tinfo; 3155 3156 PetscFunctionBegin; 3157 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3158 PetscValidType(mat,1); 3159 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3160 if (info) PetscValidPointer(info,3); 3161 PetscValidPointer(fact,4); 3162 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3163 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3164 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3165 if (!(fact)->ops->choleskyfactorsymbolic) { 3166 MatSolverType spackage; 3167 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3168 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage); 3169 } 3170 MatCheckPreallocated(mat,2); 3171 if (!info) { 3172 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3173 info = &tinfo; 3174 } 3175 3176 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3177 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 3178 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3179 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3180 PetscFunctionReturn(0); 3181 } 3182 3183 /*@C 3184 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3185 of a symmetric matrix. Call this routine after first calling 3186 MatCholeskyFactorSymbolic(). 3187 3188 Collective on Mat 3189 3190 Input Parameters: 3191 + fact - the factor matrix obtained with MatGetFactor() 3192 . mat - the initial matrix 3193 . info - options for factorization 3194 - fact - the symbolic factor of mat 3195 3196 3197 Notes: 3198 Most users should employ the simplified KSP interface for linear solvers 3199 instead of working directly with matrix algebra routines such as this. 3200 See, e.g., KSPCreate(). 3201 3202 Level: developer 3203 3204 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 3205 3206 Developer Note: fortran interface is not autogenerated as the f90 3207 interface defintion cannot be generated correctly [due to MatFactorInfo] 3208 3209 @*/ 3210 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3211 { 3212 MatFactorInfo tinfo; 3213 PetscErrorCode ierr; 3214 3215 PetscFunctionBegin; 3216 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3217 PetscValidType(mat,1); 3218 PetscValidPointer(fact,2); 3219 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3220 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3221 if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3222 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); 3223 MatCheckPreallocated(mat,2); 3224 if (!info) { 3225 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3226 info = &tinfo; 3227 } 3228 3229 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3230 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr); 3231 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3232 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3233 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3234 PetscFunctionReturn(0); 3235 } 3236 3237 /* ----------------------------------------------------------------*/ 3238 /*@ 3239 MatSolve - Solves A x = b, given a factored matrix. 3240 3241 Neighbor-wise Collective on Mat 3242 3243 Input Parameters: 3244 + mat - the factored matrix 3245 - b - the right-hand-side vector 3246 3247 Output Parameter: 3248 . x - the result vector 3249 3250 Notes: 3251 The vectors b and x cannot be the same. I.e., one cannot 3252 call MatSolve(A,x,x). 3253 3254 Notes: 3255 Most users should employ the simplified KSP interface for linear solvers 3256 instead of working directly with matrix algebra routines such as this. 3257 See, e.g., KSPCreate(). 3258 3259 Level: developer 3260 3261 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3262 @*/ 3263 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3264 { 3265 PetscErrorCode ierr; 3266 3267 PetscFunctionBegin; 3268 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3269 PetscValidType(mat,1); 3270 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3271 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3272 PetscCheckSameComm(mat,1,b,2); 3273 PetscCheckSameComm(mat,1,x,3); 3274 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3275 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); 3276 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); 3277 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); 3278 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3279 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3280 MatCheckPreallocated(mat,1); 3281 3282 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3283 if (mat->factorerrortype) { 3284 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3285 ierr = VecSetInf(x);CHKERRQ(ierr); 3286 } else { 3287 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3288 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 3289 } 3290 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3291 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3292 PetscFunctionReturn(0); 3293 } 3294 3295 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans) 3296 { 3297 PetscErrorCode ierr; 3298 Vec b,x; 3299 PetscInt m,N,i; 3300 PetscScalar *bb,*xx; 3301 3302 PetscFunctionBegin; 3303 ierr = MatDenseGetArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr); 3304 ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr); 3305 ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr); /* number local rows */ 3306 ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr); /* total columns in dense matrix */ 3307 ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr); 3308 for (i=0; i<N; i++) { 3309 ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr); 3310 ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr); 3311 if (trans) { 3312 ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr); 3313 } else { 3314 ierr = MatSolve(A,b,x);CHKERRQ(ierr); 3315 } 3316 ierr = VecResetArray(x);CHKERRQ(ierr); 3317 ierr = VecResetArray(b);CHKERRQ(ierr); 3318 } 3319 ierr = VecDestroy(&b);CHKERRQ(ierr); 3320 ierr = VecDestroy(&x);CHKERRQ(ierr); 3321 ierr = MatDenseRestoreArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr); 3322 ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr); 3323 PetscFunctionReturn(0); 3324 } 3325 3326 /*@ 3327 MatMatSolve - Solves A X = B, given a factored matrix. 3328 3329 Neighbor-wise Collective on Mat 3330 3331 Input Parameters: 3332 + A - the factored matrix 3333 - B - the right-hand-side matrix (dense matrix) 3334 3335 Output Parameter: 3336 . X - the result matrix (dense matrix) 3337 3338 Notes: 3339 The matrices b and x cannot be the same. I.e., one cannot 3340 call MatMatSolve(A,x,x). 3341 3342 Notes: 3343 Most users should usually employ the simplified KSP interface for linear solvers 3344 instead of working directly with matrix algebra routines such as this. 3345 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3346 at a time. 3347 3348 When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS 3349 it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides. 3350 3351 Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B. 3352 3353 Level: developer 3354 3355 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3356 @*/ 3357 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3358 { 3359 PetscErrorCode ierr; 3360 3361 PetscFunctionBegin; 3362 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3363 PetscValidType(A,1); 3364 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3365 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3366 PetscCheckSameComm(A,1,B,2); 3367 PetscCheckSameComm(A,1,X,3); 3368 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3369 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); 3370 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); 3371 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"); 3372 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3373 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3374 MatCheckPreallocated(A,1); 3375 3376 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3377 if (!A->ops->matsolve) { 3378 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3379 ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr); 3380 } else { 3381 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr); 3382 } 3383 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3384 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3385 PetscFunctionReturn(0); 3386 } 3387 3388 /*@ 3389 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3390 3391 Neighbor-wise Collective on Mat 3392 3393 Input Parameters: 3394 + A - the factored matrix 3395 - B - the right-hand-side matrix (dense matrix) 3396 3397 Output Parameter: 3398 . X - the result matrix (dense matrix) 3399 3400 Notes: 3401 The matrices B and X cannot be the same. I.e., one cannot 3402 call MatMatSolveTranspose(A,X,X). 3403 3404 Notes: 3405 Most users should usually employ the simplified KSP interface for linear solvers 3406 instead of working directly with matrix algebra routines such as this. 3407 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3408 at a time. 3409 3410 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3411 3412 Level: developer 3413 3414 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor() 3415 @*/ 3416 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3417 { 3418 PetscErrorCode ierr; 3419 3420 PetscFunctionBegin; 3421 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3422 PetscValidType(A,1); 3423 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3424 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3425 PetscCheckSameComm(A,1,B,2); 3426 PetscCheckSameComm(A,1,X,3); 3427 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3428 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); 3429 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); 3430 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); 3431 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"); 3432 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3433 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3434 MatCheckPreallocated(A,1); 3435 3436 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3437 if (!A->ops->matsolvetranspose) { 3438 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3439 ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr); 3440 } else { 3441 ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr); 3442 } 3443 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3444 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3445 PetscFunctionReturn(0); 3446 } 3447 3448 /*@ 3449 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3450 3451 Neighbor-wise Collective on Mat 3452 3453 Input Parameters: 3454 + A - the factored matrix 3455 - Bt - the transpose of right-hand-side matrix 3456 3457 Output Parameter: 3458 . X - the result matrix (dense matrix) 3459 3460 Notes: 3461 Most users should usually employ the simplified KSP interface for linear solvers 3462 instead of working directly with matrix algebra routines such as this. 3463 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3464 at a time. 3465 3466 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(). 3467 3468 Level: developer 3469 3470 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3471 @*/ 3472 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3473 { 3474 PetscErrorCode ierr; 3475 3476 PetscFunctionBegin; 3477 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3478 PetscValidType(A,1); 3479 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3480 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3481 PetscCheckSameComm(A,1,Bt,2); 3482 PetscCheckSameComm(A,1,X,3); 3483 3484 if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3485 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); 3486 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); 3487 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"); 3488 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3489 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3490 MatCheckPreallocated(A,1); 3491 3492 if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3493 ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3494 ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr); 3495 ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3496 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3497 PetscFunctionReturn(0); 3498 } 3499 3500 /*@ 3501 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3502 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3503 3504 Neighbor-wise Collective on Mat 3505 3506 Input Parameters: 3507 + mat - the factored matrix 3508 - b - the right-hand-side vector 3509 3510 Output Parameter: 3511 . x - the result vector 3512 3513 Notes: 3514 MatSolve() should be used for most applications, as it performs 3515 a forward solve followed by a backward solve. 3516 3517 The vectors b and x cannot be the same, i.e., one cannot 3518 call MatForwardSolve(A,x,x). 3519 3520 For matrix in seqsbaij format with block size larger than 1, 3521 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3522 MatForwardSolve() solves U^T*D y = b, and 3523 MatBackwardSolve() solves U x = y. 3524 Thus they do not provide a symmetric preconditioner. 3525 3526 Most users should employ the simplified KSP interface for linear solvers 3527 instead of working directly with matrix algebra routines such as this. 3528 See, e.g., KSPCreate(). 3529 3530 Level: developer 3531 3532 .seealso: MatSolve(), MatBackwardSolve() 3533 @*/ 3534 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3535 { 3536 PetscErrorCode ierr; 3537 3538 PetscFunctionBegin; 3539 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3540 PetscValidType(mat,1); 3541 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3542 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3543 PetscCheckSameComm(mat,1,b,2); 3544 PetscCheckSameComm(mat,1,x,3); 3545 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3546 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); 3547 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); 3548 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); 3549 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3550 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3551 MatCheckPreallocated(mat,1); 3552 3553 if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3554 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3555 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 3556 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3557 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3558 PetscFunctionReturn(0); 3559 } 3560 3561 /*@ 3562 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3563 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3564 3565 Neighbor-wise Collective on Mat 3566 3567 Input Parameters: 3568 + mat - the factored matrix 3569 - b - the right-hand-side vector 3570 3571 Output Parameter: 3572 . x - the result vector 3573 3574 Notes: 3575 MatSolve() should be used for most applications, as it performs 3576 a forward solve followed by a backward solve. 3577 3578 The vectors b and x cannot be the same. I.e., one cannot 3579 call MatBackwardSolve(A,x,x). 3580 3581 For matrix in seqsbaij format with block size larger than 1, 3582 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3583 MatForwardSolve() solves U^T*D y = b, and 3584 MatBackwardSolve() solves U x = y. 3585 Thus they do not provide a symmetric preconditioner. 3586 3587 Most users should employ the simplified KSP interface for linear solvers 3588 instead of working directly with matrix algebra routines such as this. 3589 See, e.g., KSPCreate(). 3590 3591 Level: developer 3592 3593 .seealso: MatSolve(), MatForwardSolve() 3594 @*/ 3595 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3596 { 3597 PetscErrorCode ierr; 3598 3599 PetscFunctionBegin; 3600 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3601 PetscValidType(mat,1); 3602 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3603 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3604 PetscCheckSameComm(mat,1,b,2); 3605 PetscCheckSameComm(mat,1,x,3); 3606 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3607 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); 3608 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); 3609 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); 3610 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3611 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3612 MatCheckPreallocated(mat,1); 3613 3614 if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3615 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3616 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 3617 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3618 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3619 PetscFunctionReturn(0); 3620 } 3621 3622 /*@ 3623 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3624 3625 Neighbor-wise Collective on Mat 3626 3627 Input Parameters: 3628 + mat - the factored matrix 3629 . b - the right-hand-side vector 3630 - y - the vector to be added to 3631 3632 Output Parameter: 3633 . x - the result vector 3634 3635 Notes: 3636 The vectors b and x cannot be the same. I.e., one cannot 3637 call MatSolveAdd(A,x,y,x). 3638 3639 Most users should employ the simplified KSP interface for linear solvers 3640 instead of working directly with matrix algebra routines such as this. 3641 See, e.g., KSPCreate(). 3642 3643 Level: developer 3644 3645 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3646 @*/ 3647 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3648 { 3649 PetscScalar one = 1.0; 3650 Vec tmp; 3651 PetscErrorCode ierr; 3652 3653 PetscFunctionBegin; 3654 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3655 PetscValidType(mat,1); 3656 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3657 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3658 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3659 PetscCheckSameComm(mat,1,b,2); 3660 PetscCheckSameComm(mat,1,y,2); 3661 PetscCheckSameComm(mat,1,x,3); 3662 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3663 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); 3664 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); 3665 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); 3666 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); 3667 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); 3668 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3669 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3670 MatCheckPreallocated(mat,1); 3671 3672 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3673 if (mat->ops->solveadd) { 3674 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 3675 } else { 3676 /* do the solve then the add manually */ 3677 if (x != y) { 3678 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3679 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3680 } else { 3681 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3682 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3683 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3684 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3685 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3686 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3687 } 3688 } 3689 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3690 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3691 PetscFunctionReturn(0); 3692 } 3693 3694 /*@ 3695 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3696 3697 Neighbor-wise Collective on Mat 3698 3699 Input Parameters: 3700 + mat - the factored matrix 3701 - b - the right-hand-side vector 3702 3703 Output Parameter: 3704 . x - the result vector 3705 3706 Notes: 3707 The vectors b and x cannot be the same. I.e., one cannot 3708 call MatSolveTranspose(A,x,x). 3709 3710 Most users should employ the simplified KSP interface for linear solvers 3711 instead of working directly with matrix algebra routines such as this. 3712 See, e.g., KSPCreate(). 3713 3714 Level: developer 3715 3716 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 3717 @*/ 3718 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3719 { 3720 PetscErrorCode ierr; 3721 3722 PetscFunctionBegin; 3723 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3724 PetscValidType(mat,1); 3725 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3726 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3727 PetscCheckSameComm(mat,1,b,2); 3728 PetscCheckSameComm(mat,1,x,3); 3729 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3730 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); 3731 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); 3732 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3733 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3734 MatCheckPreallocated(mat,1); 3735 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3736 if (mat->factorerrortype) { 3737 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3738 ierr = VecSetInf(x);CHKERRQ(ierr); 3739 } else { 3740 if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3741 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr); 3742 } 3743 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3744 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3745 PetscFunctionReturn(0); 3746 } 3747 3748 /*@ 3749 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3750 factored matrix. 3751 3752 Neighbor-wise Collective on Mat 3753 3754 Input Parameters: 3755 + mat - the factored matrix 3756 . b - the right-hand-side vector 3757 - y - the vector to be added to 3758 3759 Output Parameter: 3760 . x - the result vector 3761 3762 Notes: 3763 The vectors b and x cannot be the same. I.e., one cannot 3764 call MatSolveTransposeAdd(A,x,y,x). 3765 3766 Most users should employ the simplified KSP interface for linear solvers 3767 instead of working directly with matrix algebra routines such as this. 3768 See, e.g., KSPCreate(). 3769 3770 Level: developer 3771 3772 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 3773 @*/ 3774 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 3775 { 3776 PetscScalar one = 1.0; 3777 PetscErrorCode ierr; 3778 Vec tmp; 3779 3780 PetscFunctionBegin; 3781 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3782 PetscValidType(mat,1); 3783 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3784 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3785 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3786 PetscCheckSameComm(mat,1,b,2); 3787 PetscCheckSameComm(mat,1,y,3); 3788 PetscCheckSameComm(mat,1,x,4); 3789 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3790 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); 3791 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); 3792 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); 3793 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); 3794 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3795 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3796 MatCheckPreallocated(mat,1); 3797 3798 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3799 if (mat->ops->solvetransposeadd) { 3800 if (mat->factorerrortype) { 3801 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3802 ierr = VecSetInf(x);CHKERRQ(ierr); 3803 } else { 3804 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr); 3805 } 3806 } else { 3807 /* do the solve then the add manually */ 3808 if (x != y) { 3809 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3810 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3811 } else { 3812 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3813 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3814 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3815 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3816 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3817 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3818 } 3819 } 3820 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3821 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3822 PetscFunctionReturn(0); 3823 } 3824 /* ----------------------------------------------------------------*/ 3825 3826 /*@ 3827 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3828 3829 Neighbor-wise Collective on Mat 3830 3831 Input Parameters: 3832 + mat - the matrix 3833 . b - the right hand side 3834 . omega - the relaxation factor 3835 . flag - flag indicating the type of SOR (see below) 3836 . shift - diagonal shift 3837 . its - the number of iterations 3838 - lits - the number of local iterations 3839 3840 Output Parameters: 3841 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 3842 3843 SOR Flags: 3844 + SOR_FORWARD_SWEEP - forward SOR 3845 . SOR_BACKWARD_SWEEP - backward SOR 3846 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 3847 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 3848 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 3849 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 3850 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 3851 upper/lower triangular part of matrix to 3852 vector (with omega) 3853 - SOR_ZERO_INITIAL_GUESS - zero initial guess 3854 3855 Notes: 3856 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 3857 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 3858 on each processor. 3859 3860 Application programmers will not generally use MatSOR() directly, 3861 but instead will employ the KSP/PC interface. 3862 3863 Notes: 3864 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 3865 3866 Notes for Advanced Users: 3867 The flags are implemented as bitwise inclusive or operations. 3868 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 3869 to specify a zero initial guess for SSOR. 3870 3871 Most users should employ the simplified KSP interface for linear solvers 3872 instead of working directly with matrix algebra routines such as this. 3873 See, e.g., KSPCreate(). 3874 3875 Vectors x and b CANNOT be the same 3876 3877 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 3878 3879 Level: developer 3880 3881 @*/ 3882 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 3883 { 3884 PetscErrorCode ierr; 3885 3886 PetscFunctionBegin; 3887 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3888 PetscValidType(mat,1); 3889 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3890 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 3891 PetscCheckSameComm(mat,1,b,2); 3892 PetscCheckSameComm(mat,1,x,8); 3893 if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3894 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3895 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3896 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); 3897 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); 3898 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); 3899 if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its); 3900 if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits); 3901 if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 3902 3903 MatCheckPreallocated(mat,1); 3904 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3905 ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 3906 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3907 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3908 PetscFunctionReturn(0); 3909 } 3910 3911 /* 3912 Default matrix copy routine. 3913 */ 3914 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 3915 { 3916 PetscErrorCode ierr; 3917 PetscInt i,rstart = 0,rend = 0,nz; 3918 const PetscInt *cwork; 3919 const PetscScalar *vwork; 3920 3921 PetscFunctionBegin; 3922 if (B->assembled) { 3923 ierr = MatZeroEntries(B);CHKERRQ(ierr); 3924 } 3925 if (str == SAME_NONZERO_PATTERN) { 3926 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 3927 for (i=rstart; i<rend; i++) { 3928 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3929 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 3930 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3931 } 3932 } else { 3933 ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr); 3934 } 3935 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3936 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3937 PetscFunctionReturn(0); 3938 } 3939 3940 /*@ 3941 MatCopy - Copies a matrix to another matrix. 3942 3943 Collective on Mat 3944 3945 Input Parameters: 3946 + A - the matrix 3947 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 3948 3949 Output Parameter: 3950 . B - where the copy is put 3951 3952 Notes: 3953 If you use SAME_NONZERO_PATTERN then the two matrices had better have the 3954 same nonzero pattern or the routine will crash. 3955 3956 MatCopy() copies the matrix entries of a matrix to another existing 3957 matrix (after first zeroing the second matrix). A related routine is 3958 MatConvert(), which first creates a new matrix and then copies the data. 3959 3960 Level: intermediate 3961 3962 .seealso: MatConvert(), MatDuplicate() 3963 3964 @*/ 3965 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 3966 { 3967 PetscErrorCode ierr; 3968 PetscInt i; 3969 3970 PetscFunctionBegin; 3971 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3972 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3973 PetscValidType(A,1); 3974 PetscValidType(B,2); 3975 PetscCheckSameComm(A,1,B,2); 3976 MatCheckPreallocated(B,2); 3977 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3978 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3979 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); 3980 MatCheckPreallocated(A,1); 3981 if (A == B) PetscFunctionReturn(0); 3982 3983 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 3984 if (A->ops->copy) { 3985 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 3986 } else { /* generic conversion */ 3987 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 3988 } 3989 3990 B->stencil.dim = A->stencil.dim; 3991 B->stencil.noc = A->stencil.noc; 3992 for (i=0; i<=A->stencil.dim; i++) { 3993 B->stencil.dims[i] = A->stencil.dims[i]; 3994 B->stencil.starts[i] = A->stencil.starts[i]; 3995 } 3996 3997 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 3998 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 3999 PetscFunctionReturn(0); 4000 } 4001 4002 /*@C 4003 MatConvert - Converts a matrix to another matrix, either of the same 4004 or different type. 4005 4006 Collective on Mat 4007 4008 Input Parameters: 4009 + mat - the matrix 4010 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4011 same type as the original matrix. 4012 - reuse - denotes if the destination matrix is to be created or reused. 4013 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 4014 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). 4015 4016 Output Parameter: 4017 . M - pointer to place new matrix 4018 4019 Notes: 4020 MatConvert() first creates a new matrix and then copies the data from 4021 the first matrix. A related routine is MatCopy(), which copies the matrix 4022 entries of one matrix to another already existing matrix context. 4023 4024 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4025 the MPI communicator of the generated matrix is always the same as the communicator 4026 of the input matrix. 4027 4028 Level: intermediate 4029 4030 .seealso: MatCopy(), MatDuplicate() 4031 @*/ 4032 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M) 4033 { 4034 PetscErrorCode ierr; 4035 PetscBool sametype,issame,flg; 4036 char convname[256],mtype[256]; 4037 Mat B; 4038 4039 PetscFunctionBegin; 4040 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4041 PetscValidType(mat,1); 4042 PetscValidPointer(M,3); 4043 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4044 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4045 MatCheckPreallocated(mat,1); 4046 4047 ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr); 4048 if (flg) newtype = mtype; 4049 4050 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 4051 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 4052 if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4053 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"); 4054 4055 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4056 ierr = PetscInfo3(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr); 4057 PetscFunctionReturn(0); 4058 } 4059 4060 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4061 ierr = PetscInfo3(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr); 4062 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4063 } else { 4064 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4065 const char *prefix[3] = {"seq","mpi",""}; 4066 PetscInt i; 4067 /* 4068 Order of precedence: 4069 0) See if newtype is a superclass of the current matrix. 4070 1) See if a specialized converter is known to the current matrix. 4071 2) See if a specialized converter is known to the desired matrix class. 4072 3) See if a good general converter is registered for the desired class 4073 (as of 6/27/03 only MATMPIADJ falls into this category). 4074 4) See if a good general converter is known for the current matrix. 4075 5) Use a really basic converter. 4076 */ 4077 4078 /* 0) See if newtype is a superclass of the current matrix. 4079 i.e mat is mpiaij and newtype is aij */ 4080 for (i=0; i<2; i++) { 4081 ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4082 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4083 ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr); 4084 ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr); 4085 if (flg) { 4086 if (reuse == MAT_INPLACE_MATRIX) { 4087 PetscFunctionReturn(0); 4088 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4089 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4090 PetscFunctionReturn(0); 4091 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4092 ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4093 PetscFunctionReturn(0); 4094 } 4095 } 4096 } 4097 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4098 for (i=0; i<3; i++) { 4099 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4100 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4101 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4102 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4103 ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr); 4104 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4105 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr); 4106 ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4107 if (conv) goto foundconv; 4108 } 4109 4110 /* 2) See if a specialized converter is known to the desired matrix class. */ 4111 ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 4112 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr); 4113 ierr = MatSetType(B,newtype);CHKERRQ(ierr); 4114 for (i=0; i<3; i++) { 4115 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4116 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4117 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4118 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4119 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4120 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4121 ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 4122 ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4123 if (conv) { 4124 ierr = MatDestroy(&B);CHKERRQ(ierr); 4125 goto foundconv; 4126 } 4127 } 4128 4129 /* 3) See if a good general converter is registered for the desired class */ 4130 conv = B->ops->convertfrom; 4131 ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4132 ierr = MatDestroy(&B);CHKERRQ(ierr); 4133 if (conv) goto foundconv; 4134 4135 /* 4) See if a good general converter is known for the current matrix */ 4136 if (mat->ops->convert) { 4137 conv = mat->ops->convert; 4138 } 4139 ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4140 if (conv) goto foundconv; 4141 4142 /* 5) Use a really basic converter. */ 4143 ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr); 4144 conv = MatConvert_Basic; 4145 4146 foundconv: 4147 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4148 ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr); 4149 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4150 /* the block sizes must be same if the mappings are copied over */ 4151 (*M)->rmap->bs = mat->rmap->bs; 4152 (*M)->cmap->bs = mat->cmap->bs; 4153 ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr); 4154 ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr); 4155 (*M)->rmap->mapping = mat->rmap->mapping; 4156 (*M)->cmap->mapping = mat->cmap->mapping; 4157 } 4158 (*M)->stencil.dim = mat->stencil.dim; 4159 (*M)->stencil.noc = mat->stencil.noc; 4160 for (i=0; i<=mat->stencil.dim; i++) { 4161 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4162 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4163 } 4164 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4165 } 4166 ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr); 4167 4168 /* Copy Mat options */ 4169 if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);} 4170 if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);} 4171 PetscFunctionReturn(0); 4172 } 4173 4174 /*@C 4175 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4176 4177 Not Collective 4178 4179 Input Parameter: 4180 . mat - the matrix, must be a factored matrix 4181 4182 Output Parameter: 4183 . type - the string name of the package (do not free this string) 4184 4185 Notes: 4186 In Fortran you pass in a empty string and the package name will be copied into it. 4187 (Make sure the string is long enough) 4188 4189 Level: intermediate 4190 4191 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4192 @*/ 4193 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4194 { 4195 PetscErrorCode ierr, (*conv)(Mat,MatSolverType*); 4196 4197 PetscFunctionBegin; 4198 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4199 PetscValidType(mat,1); 4200 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4201 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr); 4202 if (!conv) { 4203 *type = MATSOLVERPETSC; 4204 } else { 4205 ierr = (*conv)(mat,type);CHKERRQ(ierr); 4206 } 4207 PetscFunctionReturn(0); 4208 } 4209 4210 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4211 struct _MatSolverTypeForSpecifcType { 4212 MatType mtype; 4213 PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*); 4214 MatSolverTypeForSpecifcType next; 4215 }; 4216 4217 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4218 struct _MatSolverTypeHolder { 4219 char *name; 4220 MatSolverTypeForSpecifcType handlers; 4221 MatSolverTypeHolder next; 4222 }; 4223 4224 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4225 4226 /*@C 4227 MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type 4228 4229 Input Parameters: 4230 + package - name of the package, for example petsc or superlu 4231 . mtype - the matrix type that works with this package 4232 . ftype - the type of factorization supported by the package 4233 - getfactor - routine that will create the factored matrix ready to be used 4234 4235 Level: intermediate 4236 4237 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4238 @*/ 4239 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*)) 4240 { 4241 PetscErrorCode ierr; 4242 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4243 PetscBool flg; 4244 MatSolverTypeForSpecifcType inext,iprev = NULL; 4245 4246 PetscFunctionBegin; 4247 ierr = MatInitializePackage();CHKERRQ(ierr); 4248 if (!next) { 4249 ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr); 4250 ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr); 4251 ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr); 4252 ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr); 4253 MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor; 4254 PetscFunctionReturn(0); 4255 } 4256 while (next) { 4257 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4258 if (flg) { 4259 if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4260 inext = next->handlers; 4261 while (inext) { 4262 ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4263 if (flg) { 4264 inext->getfactor[(int)ftype-1] = getfactor; 4265 PetscFunctionReturn(0); 4266 } 4267 iprev = inext; 4268 inext = inext->next; 4269 } 4270 ierr = PetscNew(&iprev->next);CHKERRQ(ierr); 4271 ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr); 4272 iprev->next->getfactor[(int)ftype-1] = getfactor; 4273 PetscFunctionReturn(0); 4274 } 4275 prev = next; 4276 next = next->next; 4277 } 4278 ierr = PetscNew(&prev->next);CHKERRQ(ierr); 4279 ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr); 4280 ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr); 4281 ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr); 4282 prev->next->handlers->getfactor[(int)ftype-1] = getfactor; 4283 PetscFunctionReturn(0); 4284 } 4285 4286 /*@C 4287 MatSolvePackageGet - Get's the function that creates the factor matrix if it exist 4288 4289 Input Parameters: 4290 + package - name of the package, for example petsc or superlu 4291 . ftype - the type of factorization supported by the package 4292 - mtype - the matrix type that works with this package 4293 4294 Output Parameters: 4295 + foundpackage - PETSC_TRUE if the package was registered 4296 . foundmtype - PETSC_TRUE if the package supports the requested mtype 4297 - getfactor - routine that will create the factored matrix ready to be used or NULL if not found 4298 4299 Level: intermediate 4300 4301 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4302 @*/ 4303 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*)) 4304 { 4305 PetscErrorCode ierr; 4306 MatSolverTypeHolder next = MatSolverTypeHolders; 4307 PetscBool flg; 4308 MatSolverTypeForSpecifcType inext; 4309 4310 PetscFunctionBegin; 4311 if (foundpackage) *foundpackage = PETSC_FALSE; 4312 if (foundmtype) *foundmtype = PETSC_FALSE; 4313 if (getfactor) *getfactor = NULL; 4314 4315 if (package) { 4316 while (next) { 4317 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4318 if (flg) { 4319 if (foundpackage) *foundpackage = PETSC_TRUE; 4320 inext = next->handlers; 4321 while (inext) { 4322 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4323 if (flg) { 4324 if (foundmtype) *foundmtype = PETSC_TRUE; 4325 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4326 PetscFunctionReturn(0); 4327 } 4328 inext = inext->next; 4329 } 4330 } 4331 next = next->next; 4332 } 4333 } else { 4334 while (next) { 4335 inext = next->handlers; 4336 while (inext) { 4337 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4338 if (flg && inext->getfactor[(int)ftype-1]) { 4339 if (foundpackage) *foundpackage = PETSC_TRUE; 4340 if (foundmtype) *foundmtype = PETSC_TRUE; 4341 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4342 PetscFunctionReturn(0); 4343 } 4344 inext = inext->next; 4345 } 4346 next = next->next; 4347 } 4348 } 4349 PetscFunctionReturn(0); 4350 } 4351 4352 PetscErrorCode MatSolverTypeDestroy(void) 4353 { 4354 PetscErrorCode ierr; 4355 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4356 MatSolverTypeForSpecifcType inext,iprev; 4357 4358 PetscFunctionBegin; 4359 while (next) { 4360 ierr = PetscFree(next->name);CHKERRQ(ierr); 4361 inext = next->handlers; 4362 while (inext) { 4363 ierr = PetscFree(inext->mtype);CHKERRQ(ierr); 4364 iprev = inext; 4365 inext = inext->next; 4366 ierr = PetscFree(iprev);CHKERRQ(ierr); 4367 } 4368 prev = next; 4369 next = next->next; 4370 ierr = PetscFree(prev);CHKERRQ(ierr); 4371 } 4372 MatSolverTypeHolders = NULL; 4373 PetscFunctionReturn(0); 4374 } 4375 4376 /*@C 4377 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4378 4379 Collective on Mat 4380 4381 Input Parameters: 4382 + mat - the matrix 4383 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4384 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4385 4386 Output Parameters: 4387 . f - the factor matrix used with MatXXFactorSymbolic() calls 4388 4389 Notes: 4390 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4391 such as pastix, superlu, mumps etc. 4392 4393 PETSc must have been ./configure to use the external solver, using the option --download-package 4394 4395 Level: intermediate 4396 4397 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4398 @*/ 4399 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4400 { 4401 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*); 4402 PetscBool foundpackage,foundmtype; 4403 4404 PetscFunctionBegin; 4405 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4406 PetscValidType(mat,1); 4407 4408 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4409 MatCheckPreallocated(mat,1); 4410 4411 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr); 4412 if (!foundpackage) { 4413 if (type) { 4414 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type); 4415 } else { 4416 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>"); 4417 } 4418 } 4419 4420 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4421 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); 4422 4423 #if defined(PETSC_USE_COMPLEX) 4424 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"); 4425 #endif 4426 4427 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4428 PetscFunctionReturn(0); 4429 } 4430 4431 /*@C 4432 MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type 4433 4434 Not Collective 4435 4436 Input Parameters: 4437 + mat - the matrix 4438 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4439 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4440 4441 Output Parameter: 4442 . flg - PETSC_TRUE if the factorization is available 4443 4444 Notes: 4445 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4446 such as pastix, superlu, mumps etc. 4447 4448 PETSc must have been ./configure to use the external solver, using the option --download-package 4449 4450 Level: intermediate 4451 4452 .seealso: MatCopy(), MatDuplicate(), MatGetFactor() 4453 @*/ 4454 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4455 { 4456 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4457 4458 PetscFunctionBegin; 4459 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4460 PetscValidType(mat,1); 4461 4462 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4463 MatCheckPreallocated(mat,1); 4464 4465 *flg = PETSC_FALSE; 4466 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4467 if (gconv) { 4468 *flg = PETSC_TRUE; 4469 } 4470 PetscFunctionReturn(0); 4471 } 4472 4473 #include <petscdmtypes.h> 4474 4475 /*@ 4476 MatDuplicate - Duplicates a matrix including the non-zero structure. 4477 4478 Collective on Mat 4479 4480 Input Parameters: 4481 + mat - the matrix 4482 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4483 See the manual page for MatDuplicateOption for an explanation of these options. 4484 4485 Output Parameter: 4486 . M - pointer to place new matrix 4487 4488 Level: intermediate 4489 4490 Notes: 4491 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4492 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. 4493 4494 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4495 @*/ 4496 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4497 { 4498 PetscErrorCode ierr; 4499 Mat B; 4500 PetscInt i; 4501 DM dm; 4502 void (*viewf)(void); 4503 4504 PetscFunctionBegin; 4505 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4506 PetscValidType(mat,1); 4507 PetscValidPointer(M,3); 4508 if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4509 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4510 MatCheckPreallocated(mat,1); 4511 4512 *M = 0; 4513 if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type"); 4514 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4515 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4516 B = *M; 4517 4518 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr); 4519 if (viewf) { 4520 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr); 4521 } 4522 4523 B->stencil.dim = mat->stencil.dim; 4524 B->stencil.noc = mat->stencil.noc; 4525 for (i=0; i<=mat->stencil.dim; i++) { 4526 B->stencil.dims[i] = mat->stencil.dims[i]; 4527 B->stencil.starts[i] = mat->stencil.starts[i]; 4528 } 4529 4530 B->nooffproczerorows = mat->nooffproczerorows; 4531 B->nooffprocentries = mat->nooffprocentries; 4532 4533 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr); 4534 if (dm) { 4535 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 4536 } 4537 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4538 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4539 PetscFunctionReturn(0); 4540 } 4541 4542 /*@ 4543 MatGetDiagonal - Gets the diagonal of a matrix. 4544 4545 Logically Collective on Mat 4546 4547 Input Parameters: 4548 + mat - the matrix 4549 - v - the vector for storing the diagonal 4550 4551 Output Parameter: 4552 . v - the diagonal of the matrix 4553 4554 Level: intermediate 4555 4556 Note: 4557 Currently only correct in parallel for square matrices. 4558 4559 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4560 @*/ 4561 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4562 { 4563 PetscErrorCode ierr; 4564 4565 PetscFunctionBegin; 4566 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4567 PetscValidType(mat,1); 4568 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4569 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4570 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4571 MatCheckPreallocated(mat,1); 4572 4573 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4574 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4575 PetscFunctionReturn(0); 4576 } 4577 4578 /*@C 4579 MatGetRowMin - Gets the minimum value (of the real part) of each 4580 row of the matrix 4581 4582 Logically Collective on Mat 4583 4584 Input Parameters: 4585 . mat - the matrix 4586 4587 Output Parameter: 4588 + v - the vector for storing the maximums 4589 - idx - the indices of the column found for each row (optional) 4590 4591 Level: intermediate 4592 4593 Notes: 4594 The result of this call are the same as if one converted the matrix to dense format 4595 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4596 4597 This code is only implemented for a couple of matrix formats. 4598 4599 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4600 MatGetRowMax() 4601 @*/ 4602 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4603 { 4604 PetscErrorCode ierr; 4605 4606 PetscFunctionBegin; 4607 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4608 PetscValidType(mat,1); 4609 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4610 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4611 if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4612 MatCheckPreallocated(mat,1); 4613 4614 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4615 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4616 PetscFunctionReturn(0); 4617 } 4618 4619 /*@C 4620 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4621 row of the matrix 4622 4623 Logically Collective on Mat 4624 4625 Input Parameters: 4626 . mat - the matrix 4627 4628 Output Parameter: 4629 + v - the vector for storing the minimums 4630 - idx - the indices of the column found for each row (or NULL if not needed) 4631 4632 Level: intermediate 4633 4634 Notes: 4635 if a row is completely empty or has only 0.0 values then the idx[] value for that 4636 row is 0 (the first column). 4637 4638 This code is only implemented for a couple of matrix formats. 4639 4640 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4641 @*/ 4642 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4643 { 4644 PetscErrorCode ierr; 4645 4646 PetscFunctionBegin; 4647 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4648 PetscValidType(mat,1); 4649 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4650 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4651 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4652 MatCheckPreallocated(mat,1); 4653 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 4654 4655 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4656 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4657 PetscFunctionReturn(0); 4658 } 4659 4660 /*@C 4661 MatGetRowMax - Gets the maximum value (of the real part) of each 4662 row of the matrix 4663 4664 Logically Collective on Mat 4665 4666 Input Parameters: 4667 . mat - the matrix 4668 4669 Output Parameter: 4670 + v - the vector for storing the maximums 4671 - idx - the indices of the column found for each row (optional) 4672 4673 Level: intermediate 4674 4675 Notes: 4676 The result of this call are the same as if one converted the matrix to dense format 4677 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4678 4679 This code is only implemented for a couple of matrix formats. 4680 4681 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4682 @*/ 4683 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4684 { 4685 PetscErrorCode ierr; 4686 4687 PetscFunctionBegin; 4688 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4689 PetscValidType(mat,1); 4690 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4691 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4692 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4693 MatCheckPreallocated(mat,1); 4694 4695 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4696 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4697 PetscFunctionReturn(0); 4698 } 4699 4700 /*@C 4701 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4702 row of the matrix 4703 4704 Logically Collective on Mat 4705 4706 Input Parameters: 4707 . mat - the matrix 4708 4709 Output Parameter: 4710 + v - the vector for storing the maximums 4711 - idx - the indices of the column found for each row (or NULL if not needed) 4712 4713 Level: intermediate 4714 4715 Notes: 4716 if a row is completely empty or has only 0.0 values then the idx[] value for that 4717 row is 0 (the first column). 4718 4719 This code is only implemented for a couple of matrix formats. 4720 4721 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4722 @*/ 4723 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4724 { 4725 PetscErrorCode ierr; 4726 4727 PetscFunctionBegin; 4728 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4729 PetscValidType(mat,1); 4730 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4731 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4732 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4733 MatCheckPreallocated(mat,1); 4734 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 4735 4736 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4737 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4738 PetscFunctionReturn(0); 4739 } 4740 4741 /*@ 4742 MatGetRowSum - Gets the sum of each row of the matrix 4743 4744 Logically or Neighborhood Collective on Mat 4745 4746 Input Parameters: 4747 . mat - the matrix 4748 4749 Output Parameter: 4750 . v - the vector for storing the sum of rows 4751 4752 Level: intermediate 4753 4754 Notes: 4755 This code is slow since it is not currently specialized for different formats 4756 4757 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4758 @*/ 4759 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4760 { 4761 Vec ones; 4762 PetscErrorCode ierr; 4763 4764 PetscFunctionBegin; 4765 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4766 PetscValidType(mat,1); 4767 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4768 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4769 MatCheckPreallocated(mat,1); 4770 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr); 4771 ierr = VecSet(ones,1.);CHKERRQ(ierr); 4772 ierr = MatMult(mat,ones,v);CHKERRQ(ierr); 4773 ierr = VecDestroy(&ones);CHKERRQ(ierr); 4774 PetscFunctionReturn(0); 4775 } 4776 4777 /*@ 4778 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4779 4780 Collective on Mat 4781 4782 Input Parameter: 4783 + mat - the matrix to transpose 4784 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 4785 4786 Output Parameters: 4787 . B - the transpose 4788 4789 Notes: 4790 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 4791 4792 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 4793 4794 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4795 4796 Level: intermediate 4797 4798 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4799 @*/ 4800 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4801 { 4802 PetscErrorCode ierr; 4803 4804 PetscFunctionBegin; 4805 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4806 PetscValidType(mat,1); 4807 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4808 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4809 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4810 if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 4811 if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 4812 MatCheckPreallocated(mat,1); 4813 4814 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4815 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 4816 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4817 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 4818 PetscFunctionReturn(0); 4819 } 4820 4821 /*@ 4822 MatIsTranspose - Test whether a matrix is another one's transpose, 4823 or its own, in which case it tests symmetry. 4824 4825 Collective on Mat 4826 4827 Input Parameter: 4828 + A - the matrix to test 4829 - B - the matrix to test against, this can equal the first parameter 4830 4831 Output Parameters: 4832 . flg - the result 4833 4834 Notes: 4835 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4836 has a running time of the order of the number of nonzeros; the parallel 4837 test involves parallel copies of the block-offdiagonal parts of the matrix. 4838 4839 Level: intermediate 4840 4841 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 4842 @*/ 4843 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4844 { 4845 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4846 4847 PetscFunctionBegin; 4848 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4849 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4850 PetscValidBoolPointer(flg,3); 4851 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 4852 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 4853 *flg = PETSC_FALSE; 4854 if (f && g) { 4855 if (f == g) { 4856 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4857 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 4858 } else { 4859 MatType mattype; 4860 if (!f) { 4861 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 4862 } else { 4863 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 4864 } 4865 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype); 4866 } 4867 PetscFunctionReturn(0); 4868 } 4869 4870 /*@ 4871 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 4872 4873 Collective on Mat 4874 4875 Input Parameter: 4876 + mat - the matrix to transpose and complex conjugate 4877 - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose 4878 4879 Output Parameters: 4880 . B - the Hermitian 4881 4882 Level: intermediate 4883 4884 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4885 @*/ 4886 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 4887 { 4888 PetscErrorCode ierr; 4889 4890 PetscFunctionBegin; 4891 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 4892 #if defined(PETSC_USE_COMPLEX) 4893 ierr = MatConjugate(*B);CHKERRQ(ierr); 4894 #endif 4895 PetscFunctionReturn(0); 4896 } 4897 4898 /*@ 4899 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 4900 4901 Collective on Mat 4902 4903 Input Parameter: 4904 + A - the matrix to test 4905 - B - the matrix to test against, this can equal the first parameter 4906 4907 Output Parameters: 4908 . flg - the result 4909 4910 Notes: 4911 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4912 has a running time of the order of the number of nonzeros; the parallel 4913 test involves parallel copies of the block-offdiagonal parts of the matrix. 4914 4915 Level: intermediate 4916 4917 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 4918 @*/ 4919 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4920 { 4921 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4922 4923 PetscFunctionBegin; 4924 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4925 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4926 PetscValidBoolPointer(flg,3); 4927 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 4928 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 4929 if (f && g) { 4930 if (f==g) { 4931 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4932 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 4933 } 4934 PetscFunctionReturn(0); 4935 } 4936 4937 /*@ 4938 MatPermute - Creates a new matrix with rows and columns permuted from the 4939 original. 4940 4941 Collective on Mat 4942 4943 Input Parameters: 4944 + mat - the matrix to permute 4945 . row - row permutation, each processor supplies only the permutation for its rows 4946 - col - column permutation, each processor supplies only the permutation for its columns 4947 4948 Output Parameters: 4949 . B - the permuted matrix 4950 4951 Level: advanced 4952 4953 Note: 4954 The index sets map from row/col of permuted matrix to row/col of original matrix. 4955 The index sets should be on the same communicator as Mat and have the same local sizes. 4956 4957 .seealso: MatGetOrdering(), ISAllGather() 4958 4959 @*/ 4960 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 4961 { 4962 PetscErrorCode ierr; 4963 4964 PetscFunctionBegin; 4965 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4966 PetscValidType(mat,1); 4967 PetscValidHeaderSpecific(row,IS_CLASSID,2); 4968 PetscValidHeaderSpecific(col,IS_CLASSID,3); 4969 PetscValidPointer(B,4); 4970 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4971 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4972 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 4973 MatCheckPreallocated(mat,1); 4974 4975 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 4976 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 4977 PetscFunctionReturn(0); 4978 } 4979 4980 /*@ 4981 MatEqual - Compares two matrices. 4982 4983 Collective on Mat 4984 4985 Input Parameters: 4986 + A - the first matrix 4987 - B - the second matrix 4988 4989 Output Parameter: 4990 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 4991 4992 Level: intermediate 4993 4994 @*/ 4995 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 4996 { 4997 PetscErrorCode ierr; 4998 4999 PetscFunctionBegin; 5000 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5001 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5002 PetscValidType(A,1); 5003 PetscValidType(B,2); 5004 PetscValidBoolPointer(flg,3); 5005 PetscCheckSameComm(A,1,B,2); 5006 MatCheckPreallocated(B,2); 5007 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5008 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5009 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); 5010 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5011 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 5012 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); 5013 MatCheckPreallocated(A,1); 5014 5015 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 5016 PetscFunctionReturn(0); 5017 } 5018 5019 /*@ 5020 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5021 matrices that are stored as vectors. Either of the two scaling 5022 matrices can be NULL. 5023 5024 Collective on Mat 5025 5026 Input Parameters: 5027 + mat - the matrix to be scaled 5028 . l - the left scaling vector (or NULL) 5029 - r - the right scaling vector (or NULL) 5030 5031 Notes: 5032 MatDiagonalScale() computes A = LAR, where 5033 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5034 The L scales the rows of the matrix, the R scales the columns of the matrix. 5035 5036 Level: intermediate 5037 5038 5039 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5040 @*/ 5041 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5042 { 5043 PetscErrorCode ierr; 5044 5045 PetscFunctionBegin; 5046 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5047 PetscValidType(mat,1); 5048 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5049 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5050 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5051 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5052 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5053 MatCheckPreallocated(mat,1); 5054 5055 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5056 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 5057 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5058 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5059 PetscFunctionReturn(0); 5060 } 5061 5062 /*@ 5063 MatScale - Scales all elements of a matrix by a given number. 5064 5065 Logically Collective on Mat 5066 5067 Input Parameters: 5068 + mat - the matrix to be scaled 5069 - a - the scaling value 5070 5071 Output Parameter: 5072 . mat - the scaled matrix 5073 5074 Level: intermediate 5075 5076 .seealso: MatDiagonalScale() 5077 @*/ 5078 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5079 { 5080 PetscErrorCode ierr; 5081 5082 PetscFunctionBegin; 5083 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5084 PetscValidType(mat,1); 5085 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5086 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5087 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5088 PetscValidLogicalCollectiveScalar(mat,a,2); 5089 MatCheckPreallocated(mat,1); 5090 5091 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5092 if (a != (PetscScalar)1.0) { 5093 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5094 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5095 } 5096 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5097 PetscFunctionReturn(0); 5098 } 5099 5100 /*@ 5101 MatNorm - Calculates various norms of a matrix. 5102 5103 Collective on Mat 5104 5105 Input Parameters: 5106 + mat - the matrix 5107 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5108 5109 Output Parameters: 5110 . nrm - the resulting norm 5111 5112 Level: intermediate 5113 5114 @*/ 5115 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5116 { 5117 PetscErrorCode ierr; 5118 5119 PetscFunctionBegin; 5120 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5121 PetscValidType(mat,1); 5122 PetscValidScalarPointer(nrm,3); 5123 5124 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5125 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5126 if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5127 MatCheckPreallocated(mat,1); 5128 5129 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5130 PetscFunctionReturn(0); 5131 } 5132 5133 /* 5134 This variable is used to prevent counting of MatAssemblyBegin() that 5135 are called from within a MatAssemblyEnd(). 5136 */ 5137 static PetscInt MatAssemblyEnd_InUse = 0; 5138 /*@ 5139 MatAssemblyBegin - Begins assembling the matrix. This routine should 5140 be called after completing all calls to MatSetValues(). 5141 5142 Collective on Mat 5143 5144 Input Parameters: 5145 + mat - the matrix 5146 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5147 5148 Notes: 5149 MatSetValues() generally caches the values. The matrix is ready to 5150 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5151 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5152 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5153 using the matrix. 5154 5155 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5156 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 5157 a global collective operation requring all processes that share the matrix. 5158 5159 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5160 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5161 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5162 5163 Level: beginner 5164 5165 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5166 @*/ 5167 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5168 { 5169 PetscErrorCode ierr; 5170 5171 PetscFunctionBegin; 5172 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5173 PetscValidType(mat,1); 5174 MatCheckPreallocated(mat,1); 5175 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5176 if (mat->assembled) { 5177 mat->was_assembled = PETSC_TRUE; 5178 mat->assembled = PETSC_FALSE; 5179 } 5180 5181 if (!MatAssemblyEnd_InUse) { 5182 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5183 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5184 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5185 } else if (mat->ops->assemblybegin) { 5186 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5187 } 5188 PetscFunctionReturn(0); 5189 } 5190 5191 /*@ 5192 MatAssembled - Indicates if a matrix has been assembled and is ready for 5193 use; for example, in matrix-vector product. 5194 5195 Not Collective 5196 5197 Input Parameter: 5198 . mat - the matrix 5199 5200 Output Parameter: 5201 . assembled - PETSC_TRUE or PETSC_FALSE 5202 5203 Level: advanced 5204 5205 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5206 @*/ 5207 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5208 { 5209 PetscFunctionBegin; 5210 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5211 PetscValidPointer(assembled,2); 5212 *assembled = mat->assembled; 5213 PetscFunctionReturn(0); 5214 } 5215 5216 /*@ 5217 MatAssemblyEnd - Completes assembling the matrix. This routine should 5218 be called after MatAssemblyBegin(). 5219 5220 Collective on Mat 5221 5222 Input Parameters: 5223 + mat - the matrix 5224 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5225 5226 Options Database Keys: 5227 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5228 . -mat_view ::ascii_info_detail - Prints more detailed info 5229 . -mat_view - Prints matrix in ASCII format 5230 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5231 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5232 . -display <name> - Sets display name (default is host) 5233 . -draw_pause <sec> - Sets number of seconds to pause after display 5234 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab ) 5235 . -viewer_socket_machine <machine> - Machine to use for socket 5236 . -viewer_socket_port <port> - Port number to use for socket 5237 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5238 5239 Notes: 5240 MatSetValues() generally caches the values. The matrix is ready to 5241 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5242 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5243 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5244 using the matrix. 5245 5246 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5247 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5248 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5249 5250 Level: beginner 5251 5252 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5253 @*/ 5254 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5255 { 5256 PetscErrorCode ierr; 5257 static PetscInt inassm = 0; 5258 PetscBool flg = PETSC_FALSE; 5259 5260 PetscFunctionBegin; 5261 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5262 PetscValidType(mat,1); 5263 5264 inassm++; 5265 MatAssemblyEnd_InUse++; 5266 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5267 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5268 if (mat->ops->assemblyend) { 5269 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5270 } 5271 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5272 } else if (mat->ops->assemblyend) { 5273 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5274 } 5275 5276 /* Flush assembly is not a true assembly */ 5277 if (type != MAT_FLUSH_ASSEMBLY) { 5278 mat->num_ass++; 5279 mat->assembled = PETSC_TRUE; 5280 mat->ass_nonzerostate = mat->nonzerostate; 5281 } 5282 5283 mat->insertmode = NOT_SET_VALUES; 5284 MatAssemblyEnd_InUse--; 5285 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5286 if (!mat->symmetric_eternal) { 5287 mat->symmetric_set = PETSC_FALSE; 5288 mat->hermitian_set = PETSC_FALSE; 5289 mat->structurally_symmetric_set = PETSC_FALSE; 5290 } 5291 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5292 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5293 5294 if (mat->checksymmetryonassembly) { 5295 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5296 if (flg) { 5297 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5298 } else { 5299 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5300 } 5301 } 5302 if (mat->nullsp && mat->checknullspaceonassembly) { 5303 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5304 } 5305 } 5306 inassm--; 5307 PetscFunctionReturn(0); 5308 } 5309 5310 /*@ 5311 MatSetOption - Sets a parameter option for a matrix. Some options 5312 may be specific to certain storage formats. Some options 5313 determine how values will be inserted (or added). Sorted, 5314 row-oriented input will generally assemble the fastest. The default 5315 is row-oriented. 5316 5317 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5318 5319 Input Parameters: 5320 + mat - the matrix 5321 . option - the option, one of those listed below (and possibly others), 5322 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5323 5324 Options Describing Matrix Structure: 5325 + MAT_SPD - symmetric positive definite 5326 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5327 . MAT_HERMITIAN - transpose is the complex conjugation 5328 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5329 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5330 you set to be kept with all future use of the matrix 5331 including after MatAssemblyBegin/End() which could 5332 potentially change the symmetry structure, i.e. you 5333 KNOW the matrix will ALWAYS have the property you set. 5334 5335 5336 Options For Use with MatSetValues(): 5337 Insert a logically dense subblock, which can be 5338 . MAT_ROW_ORIENTED - row-oriented (default) 5339 5340 Note these options reflect the data you pass in with MatSetValues(); it has 5341 nothing to do with how the data is stored internally in the matrix 5342 data structure. 5343 5344 When (re)assembling a matrix, we can restrict the input for 5345 efficiency/debugging purposes. These options include: 5346 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5347 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 5348 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5349 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5350 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5351 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5352 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5353 performance for very large process counts. 5354 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5355 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5356 functions, instead sending only neighbor messages. 5357 5358 Notes: 5359 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5360 5361 Some options are relevant only for particular matrix types and 5362 are thus ignored by others. Other options are not supported by 5363 certain matrix types and will generate an error message if set. 5364 5365 If using a Fortran 77 module to compute a matrix, one may need to 5366 use the column-oriented option (or convert to the row-oriented 5367 format). 5368 5369 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5370 that would generate a new entry in the nonzero structure is instead 5371 ignored. Thus, if memory has not alredy been allocated for this particular 5372 data, then the insertion is ignored. For dense matrices, in which 5373 the entire array is allocated, no entries are ever ignored. 5374 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5375 5376 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5377 that would generate a new entry in the nonzero structure instead produces 5378 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 5379 5380 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5381 that would generate a new entry that has not been preallocated will 5382 instead produce an error. (Currently supported for AIJ and BAIJ formats 5383 only.) This is a useful flag when debugging matrix memory preallocation. 5384 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5385 5386 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5387 other processors should be dropped, rather than stashed. 5388 This is useful if you know that the "owning" processor is also 5389 always generating the correct matrix entries, so that PETSc need 5390 not transfer duplicate entries generated on another processor. 5391 5392 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5393 searches during matrix assembly. When this flag is set, the hash table 5394 is created during the first Matrix Assembly. This hash table is 5395 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5396 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5397 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5398 supported by MATMPIBAIJ format only. 5399 5400 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5401 are kept in the nonzero structure 5402 5403 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5404 a zero location in the matrix 5405 5406 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5407 5408 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5409 zero row routines and thus improves performance for very large process counts. 5410 5411 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5412 part of the matrix (since they should match the upper triangular part). 5413 5414 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5415 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5416 with finite difference schemes with non-periodic boundary conditions. 5417 Notes: 5418 Can only be called after MatSetSizes() and MatSetType() have been set. 5419 5420 Level: intermediate 5421 5422 .seealso: MatOption, Mat 5423 5424 @*/ 5425 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5426 { 5427 PetscErrorCode ierr; 5428 5429 PetscFunctionBegin; 5430 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5431 PetscValidType(mat,1); 5432 if (op > 0) { 5433 PetscValidLogicalCollectiveEnum(mat,op,2); 5434 PetscValidLogicalCollectiveBool(mat,flg,3); 5435 } 5436 5437 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); 5438 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()"); 5439 5440 switch (op) { 5441 case MAT_NO_OFF_PROC_ENTRIES: 5442 mat->nooffprocentries = flg; 5443 PetscFunctionReturn(0); 5444 break; 5445 case MAT_SUBSET_OFF_PROC_ENTRIES: 5446 mat->assembly_subset = flg; 5447 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5448 #if !defined(PETSC_HAVE_MPIUNI) 5449 ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr); 5450 #endif 5451 mat->stash.first_assembly_done = PETSC_FALSE; 5452 } 5453 PetscFunctionReturn(0); 5454 case MAT_NO_OFF_PROC_ZERO_ROWS: 5455 mat->nooffproczerorows = flg; 5456 PetscFunctionReturn(0); 5457 break; 5458 case MAT_SPD: 5459 mat->spd_set = PETSC_TRUE; 5460 mat->spd = flg; 5461 if (flg) { 5462 mat->symmetric = PETSC_TRUE; 5463 mat->structurally_symmetric = PETSC_TRUE; 5464 mat->symmetric_set = PETSC_TRUE; 5465 mat->structurally_symmetric_set = PETSC_TRUE; 5466 } 5467 break; 5468 case MAT_SYMMETRIC: 5469 mat->symmetric = flg; 5470 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5471 mat->symmetric_set = PETSC_TRUE; 5472 mat->structurally_symmetric_set = flg; 5473 #if !defined(PETSC_USE_COMPLEX) 5474 mat->hermitian = flg; 5475 mat->hermitian_set = PETSC_TRUE; 5476 #endif 5477 break; 5478 case MAT_HERMITIAN: 5479 mat->hermitian = flg; 5480 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5481 mat->hermitian_set = PETSC_TRUE; 5482 mat->structurally_symmetric_set = flg; 5483 #if !defined(PETSC_USE_COMPLEX) 5484 mat->symmetric = flg; 5485 mat->symmetric_set = PETSC_TRUE; 5486 #endif 5487 break; 5488 case MAT_STRUCTURALLY_SYMMETRIC: 5489 mat->structurally_symmetric = flg; 5490 mat->structurally_symmetric_set = PETSC_TRUE; 5491 break; 5492 case MAT_SYMMETRY_ETERNAL: 5493 mat->symmetric_eternal = flg; 5494 break; 5495 case MAT_STRUCTURE_ONLY: 5496 mat->structure_only = flg; 5497 break; 5498 case MAT_SORTED_FULL: 5499 mat->sortedfull = flg; 5500 break; 5501 default: 5502 break; 5503 } 5504 if (mat->ops->setoption) { 5505 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5506 } 5507 PetscFunctionReturn(0); 5508 } 5509 5510 /*@ 5511 MatGetOption - Gets a parameter option that has been set for a matrix. 5512 5513 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5514 5515 Input Parameters: 5516 + mat - the matrix 5517 - option - the option, this only responds to certain options, check the code for which ones 5518 5519 Output Parameter: 5520 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5521 5522 Notes: 5523 Can only be called after MatSetSizes() and MatSetType() have been set. 5524 5525 Level: intermediate 5526 5527 .seealso: MatOption, MatSetOption() 5528 5529 @*/ 5530 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5531 { 5532 PetscFunctionBegin; 5533 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5534 PetscValidType(mat,1); 5535 5536 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); 5537 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()"); 5538 5539 switch (op) { 5540 case MAT_NO_OFF_PROC_ENTRIES: 5541 *flg = mat->nooffprocentries; 5542 break; 5543 case MAT_NO_OFF_PROC_ZERO_ROWS: 5544 *flg = mat->nooffproczerorows; 5545 break; 5546 case MAT_SYMMETRIC: 5547 *flg = mat->symmetric; 5548 break; 5549 case MAT_HERMITIAN: 5550 *flg = mat->hermitian; 5551 break; 5552 case MAT_STRUCTURALLY_SYMMETRIC: 5553 *flg = mat->structurally_symmetric; 5554 break; 5555 case MAT_SYMMETRY_ETERNAL: 5556 *flg = mat->symmetric_eternal; 5557 break; 5558 case MAT_SPD: 5559 *flg = mat->spd; 5560 break; 5561 default: 5562 break; 5563 } 5564 PetscFunctionReturn(0); 5565 } 5566 5567 /*@ 5568 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5569 this routine retains the old nonzero structure. 5570 5571 Logically Collective on Mat 5572 5573 Input Parameters: 5574 . mat - the matrix 5575 5576 Level: intermediate 5577 5578 Notes: 5579 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. 5580 See the Performance chapter of the users manual for information on preallocating matrices. 5581 5582 .seealso: MatZeroRows() 5583 @*/ 5584 PetscErrorCode MatZeroEntries(Mat mat) 5585 { 5586 PetscErrorCode ierr; 5587 5588 PetscFunctionBegin; 5589 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5590 PetscValidType(mat,1); 5591 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5592 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"); 5593 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5594 MatCheckPreallocated(mat,1); 5595 5596 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5597 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5598 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5599 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5600 PetscFunctionReturn(0); 5601 } 5602 5603 /*@ 5604 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5605 of a set of rows and columns of a matrix. 5606 5607 Collective on Mat 5608 5609 Input Parameters: 5610 + mat - the matrix 5611 . numRows - the number of rows to remove 5612 . rows - the global row indices 5613 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5614 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5615 - b - optional vector of right hand side, that will be adjusted by provided solution 5616 5617 Notes: 5618 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5619 5620 The user can set a value in the diagonal entry (or for the AIJ and 5621 row formats can optionally remove the main diagonal entry from the 5622 nonzero structure as well, by passing 0.0 as the final argument). 5623 5624 For the parallel case, all processes that share the matrix (i.e., 5625 those in the communicator used for matrix creation) MUST call this 5626 routine, regardless of whether any rows being zeroed are owned by 5627 them. 5628 5629 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5630 list only rows local to itself). 5631 5632 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5633 5634 Level: intermediate 5635 5636 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5637 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5638 @*/ 5639 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5640 { 5641 PetscErrorCode ierr; 5642 5643 PetscFunctionBegin; 5644 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5645 PetscValidType(mat,1); 5646 if (numRows) PetscValidIntPointer(rows,3); 5647 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5648 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5649 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5650 MatCheckPreallocated(mat,1); 5651 5652 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5653 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5654 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5655 PetscFunctionReturn(0); 5656 } 5657 5658 /*@ 5659 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5660 of a set of rows and columns of a matrix. 5661 5662 Collective on Mat 5663 5664 Input Parameters: 5665 + mat - the matrix 5666 . is - the rows to zero 5667 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5668 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5669 - b - optional vector of right hand side, that will be adjusted by provided solution 5670 5671 Notes: 5672 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5673 5674 The user can set a value in the diagonal entry (or for the AIJ and 5675 row formats can optionally remove the main diagonal entry from the 5676 nonzero structure as well, by passing 0.0 as the final argument). 5677 5678 For the parallel case, all processes that share the matrix (i.e., 5679 those in the communicator used for matrix creation) MUST call this 5680 routine, regardless of whether any rows being zeroed are owned by 5681 them. 5682 5683 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5684 list only rows local to itself). 5685 5686 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5687 5688 Level: intermediate 5689 5690 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5691 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 5692 @*/ 5693 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5694 { 5695 PetscErrorCode ierr; 5696 PetscInt numRows; 5697 const PetscInt *rows; 5698 5699 PetscFunctionBegin; 5700 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5701 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5702 PetscValidType(mat,1); 5703 PetscValidType(is,2); 5704 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5705 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5706 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5707 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5708 PetscFunctionReturn(0); 5709 } 5710 5711 /*@ 5712 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5713 of a set of rows of a matrix. 5714 5715 Collective on Mat 5716 5717 Input Parameters: 5718 + mat - the matrix 5719 . numRows - the number of rows to remove 5720 . rows - the global row indices 5721 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5722 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5723 - b - optional vector of right hand side, that will be adjusted by provided solution 5724 5725 Notes: 5726 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5727 but does not release memory. For the dense and block diagonal 5728 formats this does not alter the nonzero structure. 5729 5730 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5731 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5732 merely zeroed. 5733 5734 The user can set a value in the diagonal entry (or for the AIJ and 5735 row formats can optionally remove the main diagonal entry from the 5736 nonzero structure as well, by passing 0.0 as the final argument). 5737 5738 For the parallel case, all processes that share the matrix (i.e., 5739 those in the communicator used for matrix creation) MUST call this 5740 routine, regardless of whether any rows being zeroed are owned by 5741 them. 5742 5743 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5744 list only rows local to itself). 5745 5746 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5747 owns that are to be zeroed. This saves a global synchronization in the implementation. 5748 5749 Level: intermediate 5750 5751 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5752 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5753 @*/ 5754 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5755 { 5756 PetscErrorCode ierr; 5757 5758 PetscFunctionBegin; 5759 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5760 PetscValidType(mat,1); 5761 if (numRows) PetscValidIntPointer(rows,3); 5762 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5763 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5764 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5765 MatCheckPreallocated(mat,1); 5766 5767 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5768 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5769 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5770 PetscFunctionReturn(0); 5771 } 5772 5773 /*@ 5774 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5775 of a set of rows of a matrix. 5776 5777 Collective on Mat 5778 5779 Input Parameters: 5780 + mat - the matrix 5781 . is - index set of rows to remove 5782 . diag - value put in all diagonals of eliminated rows 5783 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5784 - b - optional vector of right hand side, that will be adjusted by provided solution 5785 5786 Notes: 5787 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5788 but does not release memory. For the dense and block diagonal 5789 formats this does not alter the nonzero structure. 5790 5791 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5792 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5793 merely zeroed. 5794 5795 The user can set a value in the diagonal entry (or for the AIJ and 5796 row formats can optionally remove the main diagonal entry from the 5797 nonzero structure as well, by passing 0.0 as the final argument). 5798 5799 For the parallel case, all processes that share the matrix (i.e., 5800 those in the communicator used for matrix creation) MUST call this 5801 routine, regardless of whether any rows being zeroed are owned by 5802 them. 5803 5804 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5805 list only rows local to itself). 5806 5807 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5808 owns that are to be zeroed. This saves a global synchronization in the implementation. 5809 5810 Level: intermediate 5811 5812 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5813 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5814 @*/ 5815 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5816 { 5817 PetscInt numRows; 5818 const PetscInt *rows; 5819 PetscErrorCode ierr; 5820 5821 PetscFunctionBegin; 5822 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5823 PetscValidType(mat,1); 5824 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5825 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5826 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5827 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5828 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5829 PetscFunctionReturn(0); 5830 } 5831 5832 /*@ 5833 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 5834 of a set of rows of a matrix. These rows must be local to the process. 5835 5836 Collective on Mat 5837 5838 Input Parameters: 5839 + mat - the matrix 5840 . numRows - the number of rows to remove 5841 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5842 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5843 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5844 - b - optional vector of right hand side, that will be adjusted by provided solution 5845 5846 Notes: 5847 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5848 but does not release memory. For the dense and block diagonal 5849 formats this does not alter the nonzero structure. 5850 5851 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5852 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5853 merely zeroed. 5854 5855 The user can set a value in the diagonal entry (or for the AIJ and 5856 row formats can optionally remove the main diagonal entry from the 5857 nonzero structure as well, by passing 0.0 as the final argument). 5858 5859 For the parallel case, all processes that share the matrix (i.e., 5860 those in the communicator used for matrix creation) MUST call this 5861 routine, regardless of whether any rows being zeroed are owned by 5862 them. 5863 5864 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5865 list only rows local to itself). 5866 5867 The grid coordinates are across the entire grid, not just the local portion 5868 5869 In Fortran idxm and idxn should be declared as 5870 $ MatStencil idxm(4,m) 5871 and the values inserted using 5872 $ idxm(MatStencil_i,1) = i 5873 $ idxm(MatStencil_j,1) = j 5874 $ idxm(MatStencil_k,1) = k 5875 $ idxm(MatStencil_c,1) = c 5876 etc 5877 5878 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5879 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5880 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5881 DM_BOUNDARY_PERIODIC boundary type. 5882 5883 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 5884 a single value per point) you can skip filling those indices. 5885 5886 Level: intermediate 5887 5888 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5889 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5890 @*/ 5891 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5892 { 5893 PetscInt dim = mat->stencil.dim; 5894 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5895 PetscInt *dims = mat->stencil.dims+1; 5896 PetscInt *starts = mat->stencil.starts; 5897 PetscInt *dxm = (PetscInt*) rows; 5898 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5899 PetscErrorCode ierr; 5900 5901 PetscFunctionBegin; 5902 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5903 PetscValidType(mat,1); 5904 if (numRows) PetscValidIntPointer(rows,3); 5905 5906 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 5907 for (i = 0; i < numRows; ++i) { 5908 /* Skip unused dimensions (they are ordered k, j, i, c) */ 5909 for (j = 0; j < 3-sdim; ++j) dxm++; 5910 /* Local index in X dir */ 5911 tmp = *dxm++ - starts[0]; 5912 /* Loop over remaining dimensions */ 5913 for (j = 0; j < dim-1; ++j) { 5914 /* If nonlocal, set index to be negative */ 5915 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 5916 /* Update local index */ 5917 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 5918 } 5919 /* Skip component slot if necessary */ 5920 if (mat->stencil.noc) dxm++; 5921 /* Local row number */ 5922 if (tmp >= 0) { 5923 jdxm[numNewRows++] = tmp; 5924 } 5925 } 5926 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 5927 ierr = PetscFree(jdxm);CHKERRQ(ierr); 5928 PetscFunctionReturn(0); 5929 } 5930 5931 /*@ 5932 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 5933 of a set of rows and columns of a matrix. 5934 5935 Collective on Mat 5936 5937 Input Parameters: 5938 + mat - the matrix 5939 . numRows - the number of rows/columns to remove 5940 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5941 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5942 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5943 - b - optional vector of right hand side, that will be adjusted by provided solution 5944 5945 Notes: 5946 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5947 but does not release memory. For the dense and block diagonal 5948 formats this does not alter the nonzero structure. 5949 5950 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5951 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5952 merely zeroed. 5953 5954 The user can set a value in the diagonal entry (or for the AIJ and 5955 row formats can optionally remove the main diagonal entry from the 5956 nonzero structure as well, by passing 0.0 as the final argument). 5957 5958 For the parallel case, all processes that share the matrix (i.e., 5959 those in the communicator used for matrix creation) MUST call this 5960 routine, regardless of whether any rows being zeroed are owned by 5961 them. 5962 5963 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5964 list only rows local to itself, but the row/column numbers are given in local numbering). 5965 5966 The grid coordinates are across the entire grid, not just the local portion 5967 5968 In Fortran idxm and idxn should be declared as 5969 $ MatStencil idxm(4,m) 5970 and the values inserted using 5971 $ idxm(MatStencil_i,1) = i 5972 $ idxm(MatStencil_j,1) = j 5973 $ idxm(MatStencil_k,1) = k 5974 $ idxm(MatStencil_c,1) = c 5975 etc 5976 5977 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5978 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5979 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5980 DM_BOUNDARY_PERIODIC boundary type. 5981 5982 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 5983 a single value per point) you can skip filling those indices. 5984 5985 Level: intermediate 5986 5987 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5988 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 5989 @*/ 5990 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5991 { 5992 PetscInt dim = mat->stencil.dim; 5993 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5994 PetscInt *dims = mat->stencil.dims+1; 5995 PetscInt *starts = mat->stencil.starts; 5996 PetscInt *dxm = (PetscInt*) rows; 5997 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5998 PetscErrorCode ierr; 5999 6000 PetscFunctionBegin; 6001 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6002 PetscValidType(mat,1); 6003 if (numRows) PetscValidIntPointer(rows,3); 6004 6005 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6006 for (i = 0; i < numRows; ++i) { 6007 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6008 for (j = 0; j < 3-sdim; ++j) dxm++; 6009 /* Local index in X dir */ 6010 tmp = *dxm++ - starts[0]; 6011 /* Loop over remaining dimensions */ 6012 for (j = 0; j < dim-1; ++j) { 6013 /* If nonlocal, set index to be negative */ 6014 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6015 /* Update local index */ 6016 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6017 } 6018 /* Skip component slot if necessary */ 6019 if (mat->stencil.noc) dxm++; 6020 /* Local row number */ 6021 if (tmp >= 0) { 6022 jdxm[numNewRows++] = tmp; 6023 } 6024 } 6025 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6026 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6027 PetscFunctionReturn(0); 6028 } 6029 6030 /*@C 6031 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6032 of a set of rows of a matrix; using local numbering of rows. 6033 6034 Collective on Mat 6035 6036 Input Parameters: 6037 + mat - the matrix 6038 . numRows - the number of rows to remove 6039 . rows - the global row indices 6040 . diag - value put in all diagonals of eliminated rows 6041 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6042 - b - optional vector of right hand side, that will be adjusted by provided solution 6043 6044 Notes: 6045 Before calling MatZeroRowsLocal(), the user must first set the 6046 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6047 6048 For the AIJ matrix formats this removes the old nonzero structure, 6049 but does not release memory. For the dense and block diagonal 6050 formats this does not alter the nonzero structure. 6051 6052 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6053 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6054 merely zeroed. 6055 6056 The user can set a value in the diagonal entry (or for the AIJ and 6057 row formats can optionally remove the main diagonal entry from the 6058 nonzero structure as well, by passing 0.0 as the final argument). 6059 6060 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6061 owns that are to be zeroed. This saves a global synchronization in the implementation. 6062 6063 Level: intermediate 6064 6065 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6066 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6067 @*/ 6068 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6069 { 6070 PetscErrorCode ierr; 6071 6072 PetscFunctionBegin; 6073 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6074 PetscValidType(mat,1); 6075 if (numRows) PetscValidIntPointer(rows,3); 6076 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6077 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6078 MatCheckPreallocated(mat,1); 6079 6080 if (mat->ops->zerorowslocal) { 6081 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6082 } else { 6083 IS is, newis; 6084 const PetscInt *newRows; 6085 6086 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6087 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6088 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 6089 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6090 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6091 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6092 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6093 ierr = ISDestroy(&is);CHKERRQ(ierr); 6094 } 6095 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6096 PetscFunctionReturn(0); 6097 } 6098 6099 /*@ 6100 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6101 of a set of rows of a matrix; using local numbering of rows. 6102 6103 Collective on Mat 6104 6105 Input Parameters: 6106 + mat - the matrix 6107 . is - index set of rows to remove 6108 . diag - value put in all diagonals of eliminated rows 6109 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6110 - b - optional vector of right hand side, that will be adjusted by provided solution 6111 6112 Notes: 6113 Before calling MatZeroRowsLocalIS(), the user must first set the 6114 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6115 6116 For the AIJ matrix formats this removes the old nonzero structure, 6117 but does not release memory. For the dense and block diagonal 6118 formats this does not alter the nonzero structure. 6119 6120 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6121 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6122 merely zeroed. 6123 6124 The user can set a value in the diagonal entry (or for the AIJ and 6125 row formats can optionally remove the main diagonal entry from the 6126 nonzero structure as well, by passing 0.0 as the final argument). 6127 6128 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6129 owns that are to be zeroed. This saves a global synchronization in the implementation. 6130 6131 Level: intermediate 6132 6133 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6134 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6135 @*/ 6136 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6137 { 6138 PetscErrorCode ierr; 6139 PetscInt numRows; 6140 const PetscInt *rows; 6141 6142 PetscFunctionBegin; 6143 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6144 PetscValidType(mat,1); 6145 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6146 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6147 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6148 MatCheckPreallocated(mat,1); 6149 6150 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6151 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6152 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6153 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6154 PetscFunctionReturn(0); 6155 } 6156 6157 /*@ 6158 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6159 of a set of rows and columns of a matrix; using local numbering of rows. 6160 6161 Collective on Mat 6162 6163 Input Parameters: 6164 + mat - the matrix 6165 . numRows - the number of rows to remove 6166 . rows - the global row indices 6167 . diag - value put in all diagonals of eliminated rows 6168 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6169 - b - optional vector of right hand side, that will be adjusted by provided solution 6170 6171 Notes: 6172 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6173 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6174 6175 The user can set a value in the diagonal entry (or for the AIJ and 6176 row formats can optionally remove the main diagonal entry from the 6177 nonzero structure as well, by passing 0.0 as the final argument). 6178 6179 Level: intermediate 6180 6181 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6182 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6183 @*/ 6184 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6185 { 6186 PetscErrorCode ierr; 6187 IS is, newis; 6188 const PetscInt *newRows; 6189 6190 PetscFunctionBegin; 6191 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6192 PetscValidType(mat,1); 6193 if (numRows) PetscValidIntPointer(rows,3); 6194 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6195 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6196 MatCheckPreallocated(mat,1); 6197 6198 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6199 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6200 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6201 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6202 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6203 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6204 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6205 ierr = ISDestroy(&is);CHKERRQ(ierr); 6206 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6207 PetscFunctionReturn(0); 6208 } 6209 6210 /*@ 6211 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6212 of a set of rows and columns of a matrix; using local numbering of rows. 6213 6214 Collective on Mat 6215 6216 Input Parameters: 6217 + mat - the matrix 6218 . is - index set of rows to remove 6219 . diag - value put in all diagonals of eliminated rows 6220 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6221 - b - optional vector of right hand side, that will be adjusted by provided solution 6222 6223 Notes: 6224 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6225 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6226 6227 The user can set a value in the diagonal entry (or for the AIJ and 6228 row formats can optionally remove the main diagonal entry from the 6229 nonzero structure as well, by passing 0.0 as the final argument). 6230 6231 Level: intermediate 6232 6233 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6234 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6235 @*/ 6236 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6237 { 6238 PetscErrorCode ierr; 6239 PetscInt numRows; 6240 const PetscInt *rows; 6241 6242 PetscFunctionBegin; 6243 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6244 PetscValidType(mat,1); 6245 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6246 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6247 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6248 MatCheckPreallocated(mat,1); 6249 6250 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6251 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6252 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6253 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6254 PetscFunctionReturn(0); 6255 } 6256 6257 /*@C 6258 MatGetSize - Returns the numbers of rows and columns in a matrix. 6259 6260 Not Collective 6261 6262 Input Parameter: 6263 . mat - the matrix 6264 6265 Output Parameters: 6266 + m - the number of global rows 6267 - n - the number of global columns 6268 6269 Note: both output parameters can be NULL on input. 6270 6271 Level: beginner 6272 6273 .seealso: MatGetLocalSize() 6274 @*/ 6275 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6276 { 6277 PetscFunctionBegin; 6278 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6279 if (m) *m = mat->rmap->N; 6280 if (n) *n = mat->cmap->N; 6281 PetscFunctionReturn(0); 6282 } 6283 6284 /*@C 6285 MatGetLocalSize - Returns the number of rows and columns in a matrix 6286 stored locally. This information may be implementation dependent, so 6287 use with care. 6288 6289 Not Collective 6290 6291 Input Parameters: 6292 . mat - the matrix 6293 6294 Output Parameters: 6295 + m - the number of local rows 6296 - n - the number of local columns 6297 6298 Note: both output parameters can be NULL on input. 6299 6300 Level: beginner 6301 6302 .seealso: MatGetSize() 6303 @*/ 6304 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6305 { 6306 PetscFunctionBegin; 6307 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6308 if (m) PetscValidIntPointer(m,2); 6309 if (n) PetscValidIntPointer(n,3); 6310 if (m) *m = mat->rmap->n; 6311 if (n) *n = mat->cmap->n; 6312 PetscFunctionReturn(0); 6313 } 6314 6315 /*@C 6316 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6317 this processor. (The columns of the "diagonal block") 6318 6319 Not Collective, unless matrix has not been allocated, then collective on Mat 6320 6321 Input Parameters: 6322 . mat - the matrix 6323 6324 Output Parameters: 6325 + m - the global index of the first local column 6326 - n - one more than the global index of the last local column 6327 6328 Notes: 6329 both output parameters can be NULL on input. 6330 6331 Level: developer 6332 6333 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6334 6335 @*/ 6336 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6337 { 6338 PetscFunctionBegin; 6339 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6340 PetscValidType(mat,1); 6341 if (m) PetscValidIntPointer(m,2); 6342 if (n) PetscValidIntPointer(n,3); 6343 MatCheckPreallocated(mat,1); 6344 if (m) *m = mat->cmap->rstart; 6345 if (n) *n = mat->cmap->rend; 6346 PetscFunctionReturn(0); 6347 } 6348 6349 /*@C 6350 MatGetOwnershipRange - Returns the range of matrix rows owned by 6351 this processor, assuming that the matrix is laid out with the first 6352 n1 rows on the first processor, the next n2 rows on the second, etc. 6353 For certain parallel layouts this range may not be well defined. 6354 6355 Not Collective 6356 6357 Input Parameters: 6358 . mat - the matrix 6359 6360 Output Parameters: 6361 + m - the global index of the first local row 6362 - n - one more than the global index of the last local row 6363 6364 Note: Both output parameters can be NULL on input. 6365 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6366 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6367 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6368 6369 Level: beginner 6370 6371 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6372 6373 @*/ 6374 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6375 { 6376 PetscFunctionBegin; 6377 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6378 PetscValidType(mat,1); 6379 if (m) PetscValidIntPointer(m,2); 6380 if (n) PetscValidIntPointer(n,3); 6381 MatCheckPreallocated(mat,1); 6382 if (m) *m = mat->rmap->rstart; 6383 if (n) *n = mat->rmap->rend; 6384 PetscFunctionReturn(0); 6385 } 6386 6387 /*@C 6388 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6389 each process 6390 6391 Not Collective, unless matrix has not been allocated, then collective on Mat 6392 6393 Input Parameters: 6394 . mat - the matrix 6395 6396 Output Parameters: 6397 . ranges - start of each processors portion plus one more than the total length at the end 6398 6399 Level: beginner 6400 6401 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6402 6403 @*/ 6404 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6405 { 6406 PetscErrorCode ierr; 6407 6408 PetscFunctionBegin; 6409 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6410 PetscValidType(mat,1); 6411 MatCheckPreallocated(mat,1); 6412 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6413 PetscFunctionReturn(0); 6414 } 6415 6416 /*@C 6417 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6418 this processor. (The columns of the "diagonal blocks" for each process) 6419 6420 Not Collective, unless matrix has not been allocated, then collective on Mat 6421 6422 Input Parameters: 6423 . mat - the matrix 6424 6425 Output Parameters: 6426 . ranges - start of each processors portion plus one more then the total length at the end 6427 6428 Level: beginner 6429 6430 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6431 6432 @*/ 6433 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6434 { 6435 PetscErrorCode ierr; 6436 6437 PetscFunctionBegin; 6438 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6439 PetscValidType(mat,1); 6440 MatCheckPreallocated(mat,1); 6441 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6442 PetscFunctionReturn(0); 6443 } 6444 6445 /*@C 6446 MatGetOwnershipIS - Get row and column ownership as index sets 6447 6448 Not Collective 6449 6450 Input Arguments: 6451 . A - matrix of type Elemental 6452 6453 Output Arguments: 6454 + rows - rows in which this process owns elements 6455 - cols - columns in which this process owns elements 6456 6457 Level: intermediate 6458 6459 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL 6460 @*/ 6461 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6462 { 6463 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6464 6465 PetscFunctionBegin; 6466 MatCheckPreallocated(A,1); 6467 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6468 if (f) { 6469 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6470 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6471 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6472 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6473 } 6474 PetscFunctionReturn(0); 6475 } 6476 6477 /*@C 6478 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6479 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6480 to complete the factorization. 6481 6482 Collective on Mat 6483 6484 Input Parameters: 6485 + mat - the matrix 6486 . row - row permutation 6487 . column - column permutation 6488 - info - structure containing 6489 $ levels - number of levels of fill. 6490 $ expected fill - as ratio of original fill. 6491 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6492 missing diagonal entries) 6493 6494 Output Parameters: 6495 . fact - new matrix that has been symbolically factored 6496 6497 Notes: 6498 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6499 6500 Most users should employ the simplified KSP interface for linear solvers 6501 instead of working directly with matrix algebra routines such as this. 6502 See, e.g., KSPCreate(). 6503 6504 Level: developer 6505 6506 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6507 MatGetOrdering(), MatFactorInfo 6508 6509 Note: this uses the definition of level of fill as in Y. Saad, 2003 6510 6511 Developer Note: fortran interface is not autogenerated as the f90 6512 interface defintion cannot be generated correctly [due to MatFactorInfo] 6513 6514 References: 6515 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6516 @*/ 6517 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6518 { 6519 PetscErrorCode ierr; 6520 6521 PetscFunctionBegin; 6522 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6523 PetscValidType(mat,1); 6524 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6525 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6526 PetscValidPointer(info,4); 6527 PetscValidPointer(fact,5); 6528 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6529 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6530 if (!(fact)->ops->ilufactorsymbolic) { 6531 MatSolverType spackage; 6532 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6533 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6534 } 6535 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6536 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6537 MatCheckPreallocated(mat,2); 6538 6539 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6540 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6541 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6542 PetscFunctionReturn(0); 6543 } 6544 6545 /*@C 6546 MatICCFactorSymbolic - Performs symbolic incomplete 6547 Cholesky factorization for a symmetric matrix. Use 6548 MatCholeskyFactorNumeric() to complete the factorization. 6549 6550 Collective on Mat 6551 6552 Input Parameters: 6553 + mat - the matrix 6554 . perm - row and column permutation 6555 - info - structure containing 6556 $ levels - number of levels of fill. 6557 $ expected fill - as ratio of original fill. 6558 6559 Output Parameter: 6560 . fact - the factored matrix 6561 6562 Notes: 6563 Most users should employ the KSP interface for linear solvers 6564 instead of working directly with matrix algebra routines such as this. 6565 See, e.g., KSPCreate(). 6566 6567 Level: developer 6568 6569 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6570 6571 Note: this uses the definition of level of fill as in Y. Saad, 2003 6572 6573 Developer Note: fortran interface is not autogenerated as the f90 6574 interface defintion cannot be generated correctly [due to MatFactorInfo] 6575 6576 References: 6577 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6578 @*/ 6579 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6580 { 6581 PetscErrorCode ierr; 6582 6583 PetscFunctionBegin; 6584 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6585 PetscValidType(mat,1); 6586 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6587 PetscValidPointer(info,3); 6588 PetscValidPointer(fact,4); 6589 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6590 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6591 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6592 if (!(fact)->ops->iccfactorsymbolic) { 6593 MatSolverType spackage; 6594 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6595 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6596 } 6597 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6598 MatCheckPreallocated(mat,2); 6599 6600 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6601 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6602 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6603 PetscFunctionReturn(0); 6604 } 6605 6606 /*@C 6607 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6608 points to an array of valid matrices, they may be reused to store the new 6609 submatrices. 6610 6611 Collective on Mat 6612 6613 Input Parameters: 6614 + mat - the matrix 6615 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6616 . irow, icol - index sets of rows and columns to extract 6617 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6618 6619 Output Parameter: 6620 . submat - the array of submatrices 6621 6622 Notes: 6623 MatCreateSubMatrices() can extract ONLY sequential submatrices 6624 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6625 to extract a parallel submatrix. 6626 6627 Some matrix types place restrictions on the row and column 6628 indices, such as that they be sorted or that they be equal to each other. 6629 6630 The index sets may not have duplicate entries. 6631 6632 When extracting submatrices from a parallel matrix, each processor can 6633 form a different submatrix by setting the rows and columns of its 6634 individual index sets according to the local submatrix desired. 6635 6636 When finished using the submatrices, the user should destroy 6637 them with MatDestroySubMatrices(). 6638 6639 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6640 original matrix has not changed from that last call to MatCreateSubMatrices(). 6641 6642 This routine creates the matrices in submat; you should NOT create them before 6643 calling it. It also allocates the array of matrix pointers submat. 6644 6645 For BAIJ matrices the index sets must respect the block structure, that is if they 6646 request one row/column in a block, they must request all rows/columns that are in 6647 that block. For example, if the block size is 2 you cannot request just row 0 and 6648 column 0. 6649 6650 Fortran Note: 6651 The Fortran interface is slightly different from that given below; it 6652 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6653 6654 Level: advanced 6655 6656 6657 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6658 @*/ 6659 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6660 { 6661 PetscErrorCode ierr; 6662 PetscInt i; 6663 PetscBool eq; 6664 6665 PetscFunctionBegin; 6666 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6667 PetscValidType(mat,1); 6668 if (n) { 6669 PetscValidPointer(irow,3); 6670 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6671 PetscValidPointer(icol,4); 6672 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6673 } 6674 PetscValidPointer(submat,6); 6675 if (n && scall == MAT_REUSE_MATRIX) { 6676 PetscValidPointer(*submat,6); 6677 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6678 } 6679 if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6680 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6681 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6682 MatCheckPreallocated(mat,1); 6683 6684 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6685 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6686 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6687 for (i=0; i<n; i++) { 6688 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6689 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6690 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6691 if (eq) { 6692 if (mat->symmetric) { 6693 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6694 } else if (mat->hermitian) { 6695 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6696 } else if (mat->structurally_symmetric) { 6697 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6698 } 6699 } 6700 } 6701 } 6702 PetscFunctionReturn(0); 6703 } 6704 6705 /*@C 6706 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6707 6708 Collective on Mat 6709 6710 Input Parameters: 6711 + mat - the matrix 6712 . n - the number of submatrixes to be extracted 6713 . irow, icol - index sets of rows and columns to extract 6714 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6715 6716 Output Parameter: 6717 . submat - the array of submatrices 6718 6719 Level: advanced 6720 6721 6722 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6723 @*/ 6724 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6725 { 6726 PetscErrorCode ierr; 6727 PetscInt i; 6728 PetscBool eq; 6729 6730 PetscFunctionBegin; 6731 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6732 PetscValidType(mat,1); 6733 if (n) { 6734 PetscValidPointer(irow,3); 6735 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6736 PetscValidPointer(icol,4); 6737 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6738 } 6739 PetscValidPointer(submat,6); 6740 if (n && scall == MAT_REUSE_MATRIX) { 6741 PetscValidPointer(*submat,6); 6742 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6743 } 6744 if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6745 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6746 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6747 MatCheckPreallocated(mat,1); 6748 6749 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6750 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6751 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6752 for (i=0; i<n; i++) { 6753 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6754 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6755 if (eq) { 6756 if (mat->symmetric) { 6757 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6758 } else if (mat->hermitian) { 6759 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6760 } else if (mat->structurally_symmetric) { 6761 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6762 } 6763 } 6764 } 6765 } 6766 PetscFunctionReturn(0); 6767 } 6768 6769 /*@C 6770 MatDestroyMatrices - Destroys an array of matrices. 6771 6772 Collective on Mat 6773 6774 Input Parameters: 6775 + n - the number of local matrices 6776 - mat - the matrices (note that this is a pointer to the array of matrices) 6777 6778 Level: advanced 6779 6780 Notes: 6781 Frees not only the matrices, but also the array that contains the matrices 6782 In Fortran will not free the array. 6783 6784 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 6785 @*/ 6786 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6787 { 6788 PetscErrorCode ierr; 6789 PetscInt i; 6790 6791 PetscFunctionBegin; 6792 if (!*mat) PetscFunctionReturn(0); 6793 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6794 PetscValidPointer(mat,2); 6795 6796 for (i=0; i<n; i++) { 6797 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 6798 } 6799 6800 /* memory is allocated even if n = 0 */ 6801 ierr = PetscFree(*mat);CHKERRQ(ierr); 6802 PetscFunctionReturn(0); 6803 } 6804 6805 /*@C 6806 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 6807 6808 Collective on Mat 6809 6810 Input Parameters: 6811 + n - the number of local matrices 6812 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6813 sequence of MatCreateSubMatrices()) 6814 6815 Level: advanced 6816 6817 Notes: 6818 Frees not only the matrices, but also the array that contains the matrices 6819 In Fortran will not free the array. 6820 6821 .seealso: MatCreateSubMatrices() 6822 @*/ 6823 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 6824 { 6825 PetscErrorCode ierr; 6826 Mat mat0; 6827 6828 PetscFunctionBegin; 6829 if (!*mat) PetscFunctionReturn(0); 6830 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 6831 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6832 PetscValidPointer(mat,2); 6833 6834 mat0 = (*mat)[0]; 6835 if (mat0 && mat0->ops->destroysubmatrices) { 6836 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr); 6837 } else { 6838 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr); 6839 } 6840 PetscFunctionReturn(0); 6841 } 6842 6843 /*@C 6844 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 6845 6846 Collective on Mat 6847 6848 Input Parameters: 6849 . mat - the matrix 6850 6851 Output Parameter: 6852 . matstruct - the sequential matrix with the nonzero structure of mat 6853 6854 Level: intermediate 6855 6856 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 6857 @*/ 6858 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 6859 { 6860 PetscErrorCode ierr; 6861 6862 PetscFunctionBegin; 6863 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6864 PetscValidPointer(matstruct,2); 6865 6866 PetscValidType(mat,1); 6867 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6868 MatCheckPreallocated(mat,1); 6869 6870 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 6871 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6872 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 6873 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6874 PetscFunctionReturn(0); 6875 } 6876 6877 /*@C 6878 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 6879 6880 Collective on Mat 6881 6882 Input Parameters: 6883 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 6884 sequence of MatGetSequentialNonzeroStructure()) 6885 6886 Level: advanced 6887 6888 Notes: 6889 Frees not only the matrices, but also the array that contains the matrices 6890 6891 .seealso: MatGetSeqNonzeroStructure() 6892 @*/ 6893 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 6894 { 6895 PetscErrorCode ierr; 6896 6897 PetscFunctionBegin; 6898 PetscValidPointer(mat,1); 6899 ierr = MatDestroy(mat);CHKERRQ(ierr); 6900 PetscFunctionReturn(0); 6901 } 6902 6903 /*@ 6904 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 6905 replaces the index sets by larger ones that represent submatrices with 6906 additional overlap. 6907 6908 Collective on Mat 6909 6910 Input Parameters: 6911 + mat - the matrix 6912 . n - the number of index sets 6913 . is - the array of index sets (these index sets will changed during the call) 6914 - ov - the additional overlap requested 6915 6916 Options Database: 6917 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 6918 6919 Level: developer 6920 6921 6922 .seealso: MatCreateSubMatrices() 6923 @*/ 6924 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 6925 { 6926 PetscErrorCode ierr; 6927 6928 PetscFunctionBegin; 6929 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6930 PetscValidType(mat,1); 6931 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 6932 if (n) { 6933 PetscValidPointer(is,3); 6934 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 6935 } 6936 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6937 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6938 MatCheckPreallocated(mat,1); 6939 6940 if (!ov) PetscFunctionReturn(0); 6941 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6942 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6943 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 6944 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6945 PetscFunctionReturn(0); 6946 } 6947 6948 6949 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 6950 6951 /*@ 6952 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 6953 a sub communicator, replaces the index sets by larger ones that represent submatrices with 6954 additional overlap. 6955 6956 Collective on Mat 6957 6958 Input Parameters: 6959 + mat - the matrix 6960 . n - the number of index sets 6961 . is - the array of index sets (these index sets will changed during the call) 6962 - ov - the additional overlap requested 6963 6964 Options Database: 6965 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 6966 6967 Level: developer 6968 6969 6970 .seealso: MatCreateSubMatrices() 6971 @*/ 6972 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 6973 { 6974 PetscInt i; 6975 PetscErrorCode ierr; 6976 6977 PetscFunctionBegin; 6978 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6979 PetscValidType(mat,1); 6980 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 6981 if (n) { 6982 PetscValidPointer(is,3); 6983 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 6984 } 6985 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6986 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6987 MatCheckPreallocated(mat,1); 6988 if (!ov) PetscFunctionReturn(0); 6989 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6990 for(i=0; i<n; i++){ 6991 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 6992 } 6993 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6994 PetscFunctionReturn(0); 6995 } 6996 6997 6998 6999 7000 /*@ 7001 MatGetBlockSize - Returns the matrix block size. 7002 7003 Not Collective 7004 7005 Input Parameter: 7006 . mat - the matrix 7007 7008 Output Parameter: 7009 . bs - block size 7010 7011 Notes: 7012 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7013 7014 If the block size has not been set yet this routine returns 1. 7015 7016 Level: intermediate 7017 7018 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7019 @*/ 7020 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7021 { 7022 PetscFunctionBegin; 7023 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7024 PetscValidIntPointer(bs,2); 7025 *bs = PetscAbs(mat->rmap->bs); 7026 PetscFunctionReturn(0); 7027 } 7028 7029 /*@ 7030 MatGetBlockSizes - Returns the matrix block row and column sizes. 7031 7032 Not Collective 7033 7034 Input Parameter: 7035 . mat - the matrix 7036 7037 Output Parameter: 7038 + rbs - row block size 7039 - cbs - column block size 7040 7041 Notes: 7042 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7043 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7044 7045 If a block size has not been set yet this routine returns 1. 7046 7047 Level: intermediate 7048 7049 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7050 @*/ 7051 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7052 { 7053 PetscFunctionBegin; 7054 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7055 if (rbs) PetscValidIntPointer(rbs,2); 7056 if (cbs) PetscValidIntPointer(cbs,3); 7057 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7058 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7059 PetscFunctionReturn(0); 7060 } 7061 7062 /*@ 7063 MatSetBlockSize - Sets the matrix block size. 7064 7065 Logically Collective on Mat 7066 7067 Input Parameters: 7068 + mat - the matrix 7069 - bs - block size 7070 7071 Notes: 7072 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7073 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7074 7075 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7076 is compatible with the matrix local sizes. 7077 7078 Level: intermediate 7079 7080 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7081 @*/ 7082 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7083 { 7084 PetscErrorCode ierr; 7085 7086 PetscFunctionBegin; 7087 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7088 PetscValidLogicalCollectiveInt(mat,bs,2); 7089 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr); 7090 PetscFunctionReturn(0); 7091 } 7092 7093 /*@ 7094 MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size 7095 7096 Logically Collective on Mat 7097 7098 Input Parameters: 7099 + mat - the matrix 7100 . nblocks - the number of blocks on this process 7101 - bsizes - the block sizes 7102 7103 Notes: 7104 Currently used by PCVPBJACOBI for SeqAIJ matrices 7105 7106 Level: intermediate 7107 7108 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes() 7109 @*/ 7110 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7111 { 7112 PetscErrorCode ierr; 7113 PetscInt i,ncnt = 0, nlocal; 7114 7115 PetscFunctionBegin; 7116 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7117 if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7118 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr); 7119 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7120 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); 7121 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr); 7122 mat->nblocks = nblocks; 7123 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr); 7124 ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr); 7125 PetscFunctionReturn(0); 7126 } 7127 7128 /*@C 7129 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7130 7131 Logically Collective on Mat 7132 7133 Input Parameters: 7134 . mat - the matrix 7135 7136 Output Parameters: 7137 + nblocks - the number of blocks on this process 7138 - bsizes - the block sizes 7139 7140 Notes: Currently not supported from Fortran 7141 7142 Level: intermediate 7143 7144 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7145 @*/ 7146 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7147 { 7148 PetscFunctionBegin; 7149 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7150 *nblocks = mat->nblocks; 7151 *bsizes = mat->bsizes; 7152 PetscFunctionReturn(0); 7153 } 7154 7155 /*@ 7156 MatSetBlockSizes - Sets the matrix block row and column sizes. 7157 7158 Logically Collective on Mat 7159 7160 Input Parameters: 7161 + mat - the matrix 7162 - rbs - row block size 7163 - cbs - column block size 7164 7165 Notes: 7166 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7167 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7168 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 7169 7170 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7171 are compatible with the matrix local sizes. 7172 7173 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7174 7175 Level: intermediate 7176 7177 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7178 @*/ 7179 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7180 { 7181 PetscErrorCode ierr; 7182 7183 PetscFunctionBegin; 7184 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7185 PetscValidLogicalCollectiveInt(mat,rbs,2); 7186 PetscValidLogicalCollectiveInt(mat,cbs,3); 7187 if (mat->ops->setblocksizes) { 7188 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr); 7189 } 7190 if (mat->rmap->refcnt) { 7191 ISLocalToGlobalMapping l2g = NULL; 7192 PetscLayout nmap = NULL; 7193 7194 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr); 7195 if (mat->rmap->mapping) { 7196 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr); 7197 } 7198 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr); 7199 mat->rmap = nmap; 7200 mat->rmap->mapping = l2g; 7201 } 7202 if (mat->cmap->refcnt) { 7203 ISLocalToGlobalMapping l2g = NULL; 7204 PetscLayout nmap = NULL; 7205 7206 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr); 7207 if (mat->cmap->mapping) { 7208 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr); 7209 } 7210 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 7211 mat->cmap = nmap; 7212 mat->cmap->mapping = l2g; 7213 } 7214 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7215 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7216 PetscFunctionReturn(0); 7217 } 7218 7219 /*@ 7220 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7221 7222 Logically Collective on Mat 7223 7224 Input Parameters: 7225 + mat - the matrix 7226 . fromRow - matrix from which to copy row block size 7227 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7228 7229 Level: developer 7230 7231 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7232 @*/ 7233 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7234 { 7235 PetscErrorCode ierr; 7236 7237 PetscFunctionBegin; 7238 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7239 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7240 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7241 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7242 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7243 PetscFunctionReturn(0); 7244 } 7245 7246 /*@ 7247 MatResidual - Default routine to calculate the residual. 7248 7249 Collective on Mat 7250 7251 Input Parameters: 7252 + mat - the matrix 7253 . b - the right-hand-side 7254 - x - the approximate solution 7255 7256 Output Parameter: 7257 . r - location to store the residual 7258 7259 Level: developer 7260 7261 .seealso: PCMGSetResidual() 7262 @*/ 7263 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7264 { 7265 PetscErrorCode ierr; 7266 7267 PetscFunctionBegin; 7268 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7269 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7270 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7271 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7272 PetscValidType(mat,1); 7273 MatCheckPreallocated(mat,1); 7274 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7275 if (!mat->ops->residual) { 7276 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7277 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7278 } else { 7279 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7280 } 7281 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7282 PetscFunctionReturn(0); 7283 } 7284 7285 /*@C 7286 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7287 7288 Collective on Mat 7289 7290 Input Parameters: 7291 + mat - the matrix 7292 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7293 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7294 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7295 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7296 always used. 7297 7298 Output Parameters: 7299 + n - number of rows in the (possibly compressed) matrix 7300 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7301 . ja - the column indices 7302 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7303 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7304 7305 Level: developer 7306 7307 Notes: 7308 You CANNOT change any of the ia[] or ja[] values. 7309 7310 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7311 7312 Fortran Notes: 7313 In Fortran use 7314 $ 7315 $ PetscInt ia(1), ja(1) 7316 $ PetscOffset iia, jja 7317 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7318 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7319 7320 or 7321 $ 7322 $ PetscInt, pointer :: ia(:),ja(:) 7323 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7324 $ ! Access the ith and jth entries via ia(i) and ja(j) 7325 7326 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7327 @*/ 7328 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7329 { 7330 PetscErrorCode ierr; 7331 7332 PetscFunctionBegin; 7333 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7334 PetscValidType(mat,1); 7335 PetscValidIntPointer(n,5); 7336 if (ia) PetscValidIntPointer(ia,6); 7337 if (ja) PetscValidIntPointer(ja,7); 7338 PetscValidIntPointer(done,8); 7339 MatCheckPreallocated(mat,1); 7340 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7341 else { 7342 *done = PETSC_TRUE; 7343 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7344 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7345 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7346 } 7347 PetscFunctionReturn(0); 7348 } 7349 7350 /*@C 7351 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7352 7353 Collective on Mat 7354 7355 Input Parameters: 7356 + mat - the matrix 7357 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7358 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7359 symmetrized 7360 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7361 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7362 always used. 7363 . n - number of columns in the (possibly compressed) matrix 7364 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7365 - ja - the row indices 7366 7367 Output Parameters: 7368 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7369 7370 Level: developer 7371 7372 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7373 @*/ 7374 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7375 { 7376 PetscErrorCode ierr; 7377 7378 PetscFunctionBegin; 7379 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7380 PetscValidType(mat,1); 7381 PetscValidIntPointer(n,4); 7382 if (ia) PetscValidIntPointer(ia,5); 7383 if (ja) PetscValidIntPointer(ja,6); 7384 PetscValidIntPointer(done,7); 7385 MatCheckPreallocated(mat,1); 7386 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7387 else { 7388 *done = PETSC_TRUE; 7389 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7390 } 7391 PetscFunctionReturn(0); 7392 } 7393 7394 /*@C 7395 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7396 MatGetRowIJ(). 7397 7398 Collective on Mat 7399 7400 Input Parameters: 7401 + mat - the matrix 7402 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7403 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7404 symmetrized 7405 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7406 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7407 always used. 7408 . n - size of (possibly compressed) matrix 7409 . ia - the row pointers 7410 - ja - the column indices 7411 7412 Output Parameters: 7413 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7414 7415 Note: 7416 This routine zeros out n, ia, and ja. This is to prevent accidental 7417 us of the array after it has been restored. If you pass NULL, it will 7418 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7419 7420 Level: developer 7421 7422 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7423 @*/ 7424 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7425 { 7426 PetscErrorCode ierr; 7427 7428 PetscFunctionBegin; 7429 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7430 PetscValidType(mat,1); 7431 if (ia) PetscValidIntPointer(ia,6); 7432 if (ja) PetscValidIntPointer(ja,7); 7433 PetscValidIntPointer(done,8); 7434 MatCheckPreallocated(mat,1); 7435 7436 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7437 else { 7438 *done = PETSC_TRUE; 7439 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7440 if (n) *n = 0; 7441 if (ia) *ia = NULL; 7442 if (ja) *ja = NULL; 7443 } 7444 PetscFunctionReturn(0); 7445 } 7446 7447 /*@C 7448 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7449 MatGetColumnIJ(). 7450 7451 Collective on Mat 7452 7453 Input Parameters: 7454 + mat - the matrix 7455 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7456 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7457 symmetrized 7458 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7459 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7460 always used. 7461 7462 Output Parameters: 7463 + n - size of (possibly compressed) matrix 7464 . ia - the column pointers 7465 . ja - the row indices 7466 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7467 7468 Level: developer 7469 7470 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7471 @*/ 7472 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7473 { 7474 PetscErrorCode ierr; 7475 7476 PetscFunctionBegin; 7477 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7478 PetscValidType(mat,1); 7479 if (ia) PetscValidIntPointer(ia,5); 7480 if (ja) PetscValidIntPointer(ja,6); 7481 PetscValidIntPointer(done,7); 7482 MatCheckPreallocated(mat,1); 7483 7484 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7485 else { 7486 *done = PETSC_TRUE; 7487 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7488 if (n) *n = 0; 7489 if (ia) *ia = NULL; 7490 if (ja) *ja = NULL; 7491 } 7492 PetscFunctionReturn(0); 7493 } 7494 7495 /*@C 7496 MatColoringPatch -Used inside matrix coloring routines that 7497 use MatGetRowIJ() and/or MatGetColumnIJ(). 7498 7499 Collective on Mat 7500 7501 Input Parameters: 7502 + mat - the matrix 7503 . ncolors - max color value 7504 . n - number of entries in colorarray 7505 - colorarray - array indicating color for each column 7506 7507 Output Parameters: 7508 . iscoloring - coloring generated using colorarray information 7509 7510 Level: developer 7511 7512 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7513 7514 @*/ 7515 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7516 { 7517 PetscErrorCode ierr; 7518 7519 PetscFunctionBegin; 7520 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7521 PetscValidType(mat,1); 7522 PetscValidIntPointer(colorarray,4); 7523 PetscValidPointer(iscoloring,5); 7524 MatCheckPreallocated(mat,1); 7525 7526 if (!mat->ops->coloringpatch) { 7527 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7528 } else { 7529 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7530 } 7531 PetscFunctionReturn(0); 7532 } 7533 7534 7535 /*@ 7536 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7537 7538 Logically Collective on Mat 7539 7540 Input Parameter: 7541 . mat - the factored matrix to be reset 7542 7543 Notes: 7544 This routine should be used only with factored matrices formed by in-place 7545 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7546 format). This option can save memory, for example, when solving nonlinear 7547 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7548 ILU(0) preconditioner. 7549 7550 Note that one can specify in-place ILU(0) factorization by calling 7551 .vb 7552 PCType(pc,PCILU); 7553 PCFactorSeUseInPlace(pc); 7554 .ve 7555 or by using the options -pc_type ilu -pc_factor_in_place 7556 7557 In-place factorization ILU(0) can also be used as a local 7558 solver for the blocks within the block Jacobi or additive Schwarz 7559 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7560 for details on setting local solver options. 7561 7562 Most users should employ the simplified KSP interface for linear solvers 7563 instead of working directly with matrix algebra routines such as this. 7564 See, e.g., KSPCreate(). 7565 7566 Level: developer 7567 7568 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7569 7570 @*/ 7571 PetscErrorCode MatSetUnfactored(Mat mat) 7572 { 7573 PetscErrorCode ierr; 7574 7575 PetscFunctionBegin; 7576 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7577 PetscValidType(mat,1); 7578 MatCheckPreallocated(mat,1); 7579 mat->factortype = MAT_FACTOR_NONE; 7580 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7581 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7582 PetscFunctionReturn(0); 7583 } 7584 7585 /*MC 7586 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7587 7588 Synopsis: 7589 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7590 7591 Not collective 7592 7593 Input Parameter: 7594 . x - matrix 7595 7596 Output Parameters: 7597 + xx_v - the Fortran90 pointer to the array 7598 - ierr - error code 7599 7600 Example of Usage: 7601 .vb 7602 PetscScalar, pointer xx_v(:,:) 7603 .... 7604 call MatDenseGetArrayF90(x,xx_v,ierr) 7605 a = xx_v(3) 7606 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7607 .ve 7608 7609 Level: advanced 7610 7611 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7612 7613 M*/ 7614 7615 /*MC 7616 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7617 accessed with MatDenseGetArrayF90(). 7618 7619 Synopsis: 7620 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7621 7622 Not collective 7623 7624 Input Parameters: 7625 + x - matrix 7626 - xx_v - the Fortran90 pointer to the array 7627 7628 Output Parameter: 7629 . ierr - error code 7630 7631 Example of Usage: 7632 .vb 7633 PetscScalar, pointer xx_v(:,:) 7634 .... 7635 call MatDenseGetArrayF90(x,xx_v,ierr) 7636 a = xx_v(3) 7637 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7638 .ve 7639 7640 Level: advanced 7641 7642 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7643 7644 M*/ 7645 7646 7647 /*MC 7648 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7649 7650 Synopsis: 7651 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7652 7653 Not collective 7654 7655 Input Parameter: 7656 . x - matrix 7657 7658 Output Parameters: 7659 + xx_v - the Fortran90 pointer to the array 7660 - ierr - error code 7661 7662 Example of Usage: 7663 .vb 7664 PetscScalar, pointer xx_v(:) 7665 .... 7666 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7667 a = xx_v(3) 7668 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7669 .ve 7670 7671 Level: advanced 7672 7673 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7674 7675 M*/ 7676 7677 /*MC 7678 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7679 accessed with MatSeqAIJGetArrayF90(). 7680 7681 Synopsis: 7682 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7683 7684 Not collective 7685 7686 Input Parameters: 7687 + x - matrix 7688 - xx_v - the Fortran90 pointer to the array 7689 7690 Output Parameter: 7691 . ierr - error code 7692 7693 Example of Usage: 7694 .vb 7695 PetscScalar, pointer xx_v(:) 7696 .... 7697 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7698 a = xx_v(3) 7699 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7700 .ve 7701 7702 Level: advanced 7703 7704 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7705 7706 M*/ 7707 7708 7709 /*@ 7710 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7711 as the original matrix. 7712 7713 Collective on Mat 7714 7715 Input Parameters: 7716 + mat - the original matrix 7717 . isrow - parallel IS containing the rows this processor should obtain 7718 . 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. 7719 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7720 7721 Output Parameter: 7722 . newmat - the new submatrix, of the same type as the old 7723 7724 Level: advanced 7725 7726 Notes: 7727 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7728 7729 Some matrix types place restrictions on the row and column indices, such 7730 as that they be sorted or that they be equal to each other. 7731 7732 The index sets may not have duplicate entries. 7733 7734 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7735 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 7736 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7737 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7738 you are finished using it. 7739 7740 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7741 the input matrix. 7742 7743 If iscol is NULL then all columns are obtained (not supported in Fortran). 7744 7745 Example usage: 7746 Consider the following 8x8 matrix with 34 non-zero values, that is 7747 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7748 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7749 as follows: 7750 7751 .vb 7752 1 2 0 | 0 3 0 | 0 4 7753 Proc0 0 5 6 | 7 0 0 | 8 0 7754 9 0 10 | 11 0 0 | 12 0 7755 ------------------------------------- 7756 13 0 14 | 15 16 17 | 0 0 7757 Proc1 0 18 0 | 19 20 21 | 0 0 7758 0 0 0 | 22 23 0 | 24 0 7759 ------------------------------------- 7760 Proc2 25 26 27 | 0 0 28 | 29 0 7761 30 0 0 | 31 32 33 | 0 34 7762 .ve 7763 7764 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7765 7766 .vb 7767 2 0 | 0 3 0 | 0 7768 Proc0 5 6 | 7 0 0 | 8 7769 ------------------------------- 7770 Proc1 18 0 | 19 20 21 | 0 7771 ------------------------------- 7772 Proc2 26 27 | 0 0 28 | 29 7773 0 0 | 31 32 33 | 0 7774 .ve 7775 7776 7777 .seealso: MatCreateSubMatrices() 7778 @*/ 7779 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7780 { 7781 PetscErrorCode ierr; 7782 PetscMPIInt size; 7783 Mat *local; 7784 IS iscoltmp; 7785 7786 PetscFunctionBegin; 7787 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7788 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7789 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7790 PetscValidPointer(newmat,5); 7791 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7792 PetscValidType(mat,1); 7793 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7794 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 7795 7796 MatCheckPreallocated(mat,1); 7797 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 7798 7799 if (!iscol || isrow == iscol) { 7800 PetscBool stride; 7801 PetscMPIInt grabentirematrix = 0,grab; 7802 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 7803 if (stride) { 7804 PetscInt first,step,n,rstart,rend; 7805 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 7806 if (step == 1) { 7807 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 7808 if (rstart == first) { 7809 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 7810 if (n == rend-rstart) { 7811 grabentirematrix = 1; 7812 } 7813 } 7814 } 7815 } 7816 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 7817 if (grab) { 7818 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 7819 if (cll == MAT_INITIAL_MATRIX) { 7820 *newmat = mat; 7821 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 7822 } 7823 PetscFunctionReturn(0); 7824 } 7825 } 7826 7827 if (!iscol) { 7828 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 7829 } else { 7830 iscoltmp = iscol; 7831 } 7832 7833 /* if original matrix is on just one processor then use submatrix generated */ 7834 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 7835 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 7836 goto setproperties; 7837 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 7838 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 7839 *newmat = *local; 7840 ierr = PetscFree(local);CHKERRQ(ierr); 7841 goto setproperties; 7842 } else if (!mat->ops->createsubmatrix) { 7843 /* Create a new matrix type that implements the operation using the full matrix */ 7844 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7845 switch (cll) { 7846 case MAT_INITIAL_MATRIX: 7847 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 7848 break; 7849 case MAT_REUSE_MATRIX: 7850 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 7851 break; 7852 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 7853 } 7854 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7855 goto setproperties; 7856 } 7857 7858 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7859 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7860 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 7861 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7862 7863 /* Propagate symmetry information for diagonal blocks */ 7864 setproperties: 7865 if (isrow == iscoltmp) { 7866 if (mat->symmetric_set && mat->symmetric) { 7867 ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 7868 } 7869 if (mat->structurally_symmetric_set && mat->structurally_symmetric) { 7870 ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 7871 } 7872 if (mat->hermitian_set && mat->hermitian) { 7873 ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 7874 } 7875 if (mat->spd_set && mat->spd) { 7876 ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 7877 } 7878 } 7879 7880 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7881 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 7882 PetscFunctionReturn(0); 7883 } 7884 7885 /*@ 7886 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 7887 used during the assembly process to store values that belong to 7888 other processors. 7889 7890 Not Collective 7891 7892 Input Parameters: 7893 + mat - the matrix 7894 . size - the initial size of the stash. 7895 - bsize - the initial size of the block-stash(if used). 7896 7897 Options Database Keys: 7898 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 7899 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 7900 7901 Level: intermediate 7902 7903 Notes: 7904 The block-stash is used for values set with MatSetValuesBlocked() while 7905 the stash is used for values set with MatSetValues() 7906 7907 Run with the option -info and look for output of the form 7908 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 7909 to determine the appropriate value, MM, to use for size and 7910 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 7911 to determine the value, BMM to use for bsize 7912 7913 7914 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 7915 7916 @*/ 7917 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 7918 { 7919 PetscErrorCode ierr; 7920 7921 PetscFunctionBegin; 7922 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7923 PetscValidType(mat,1); 7924 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 7925 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 7926 PetscFunctionReturn(0); 7927 } 7928 7929 /*@ 7930 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 7931 the matrix 7932 7933 Neighbor-wise Collective on Mat 7934 7935 Input Parameters: 7936 + mat - the matrix 7937 . x,y - the vectors 7938 - w - where the result is stored 7939 7940 Level: intermediate 7941 7942 Notes: 7943 w may be the same vector as y. 7944 7945 This allows one to use either the restriction or interpolation (its transpose) 7946 matrix to do the interpolation 7947 7948 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 7949 7950 @*/ 7951 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 7952 { 7953 PetscErrorCode ierr; 7954 PetscInt M,N,Ny; 7955 7956 PetscFunctionBegin; 7957 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7958 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7959 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 7960 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 7961 PetscValidType(A,1); 7962 MatCheckPreallocated(A,1); 7963 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 7964 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 7965 if (M == Ny) { 7966 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 7967 } else { 7968 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 7969 } 7970 PetscFunctionReturn(0); 7971 } 7972 7973 /*@ 7974 MatInterpolate - y = A*x or A'*x depending on the shape of 7975 the matrix 7976 7977 Neighbor-wise Collective on Mat 7978 7979 Input Parameters: 7980 + mat - the matrix 7981 - x,y - the vectors 7982 7983 Level: intermediate 7984 7985 Notes: 7986 This allows one to use either the restriction or interpolation (its transpose) 7987 matrix to do the interpolation 7988 7989 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 7990 7991 @*/ 7992 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 7993 { 7994 PetscErrorCode ierr; 7995 PetscInt M,N,Ny; 7996 7997 PetscFunctionBegin; 7998 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7999 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8000 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8001 PetscValidType(A,1); 8002 MatCheckPreallocated(A,1); 8003 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8004 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8005 if (M == Ny) { 8006 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8007 } else { 8008 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8009 } 8010 PetscFunctionReturn(0); 8011 } 8012 8013 /*@ 8014 MatRestrict - y = A*x or A'*x 8015 8016 Neighbor-wise Collective on Mat 8017 8018 Input Parameters: 8019 + mat - the matrix 8020 - x,y - the vectors 8021 8022 Level: intermediate 8023 8024 Notes: 8025 This allows one to use either the restriction or interpolation (its transpose) 8026 matrix to do the restriction 8027 8028 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8029 8030 @*/ 8031 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8032 { 8033 PetscErrorCode ierr; 8034 PetscInt M,N,Ny; 8035 8036 PetscFunctionBegin; 8037 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8038 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8039 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8040 PetscValidType(A,1); 8041 MatCheckPreallocated(A,1); 8042 8043 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8044 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8045 if (M == Ny) { 8046 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8047 } else { 8048 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8049 } 8050 PetscFunctionReturn(0); 8051 } 8052 8053 /*@ 8054 MatGetNullSpace - retrieves the null space of a matrix. 8055 8056 Logically Collective on Mat 8057 8058 Input Parameters: 8059 + mat - the matrix 8060 - nullsp - the null space object 8061 8062 Level: developer 8063 8064 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8065 @*/ 8066 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8067 { 8068 PetscFunctionBegin; 8069 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8070 PetscValidPointer(nullsp,2); 8071 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8072 PetscFunctionReturn(0); 8073 } 8074 8075 /*@ 8076 MatSetNullSpace - attaches a null space to a matrix. 8077 8078 Logically Collective on Mat 8079 8080 Input Parameters: 8081 + mat - the matrix 8082 - nullsp - the null space object 8083 8084 Level: advanced 8085 8086 Notes: 8087 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8088 8089 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8090 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8091 8092 You can remove the null space by calling this routine with an nullsp of NULL 8093 8094 8095 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8096 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). 8097 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 8098 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 8099 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). 8100 8101 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8102 8103 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 8104 routine also automatically calls MatSetTransposeNullSpace(). 8105 8106 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8107 @*/ 8108 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8109 { 8110 PetscErrorCode ierr; 8111 8112 PetscFunctionBegin; 8113 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8114 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8115 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8116 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8117 mat->nullsp = nullsp; 8118 if (mat->symmetric_set && mat->symmetric) { 8119 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8120 } 8121 PetscFunctionReturn(0); 8122 } 8123 8124 /*@ 8125 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8126 8127 Logically Collective on Mat 8128 8129 Input Parameters: 8130 + mat - the matrix 8131 - nullsp - the null space object 8132 8133 Level: developer 8134 8135 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8136 @*/ 8137 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8138 { 8139 PetscFunctionBegin; 8140 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8141 PetscValidType(mat,1); 8142 PetscValidPointer(nullsp,2); 8143 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8144 PetscFunctionReturn(0); 8145 } 8146 8147 /*@ 8148 MatSetTransposeNullSpace - attaches a null space to a matrix. 8149 8150 Logically Collective on Mat 8151 8152 Input Parameters: 8153 + mat - the matrix 8154 - nullsp - the null space object 8155 8156 Level: advanced 8157 8158 Notes: 8159 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. 8160 You must also call MatSetNullSpace() 8161 8162 8163 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8164 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). 8165 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 8166 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 8167 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). 8168 8169 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8170 8171 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8172 @*/ 8173 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8174 { 8175 PetscErrorCode ierr; 8176 8177 PetscFunctionBegin; 8178 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8179 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8180 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8181 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8182 mat->transnullsp = nullsp; 8183 PetscFunctionReturn(0); 8184 } 8185 8186 /*@ 8187 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8188 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8189 8190 Logically Collective on Mat 8191 8192 Input Parameters: 8193 + mat - the matrix 8194 - nullsp - the null space object 8195 8196 Level: advanced 8197 8198 Notes: 8199 Overwrites any previous near null space that may have been attached 8200 8201 You can remove the null space by calling this routine with an nullsp of NULL 8202 8203 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8204 @*/ 8205 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8206 { 8207 PetscErrorCode ierr; 8208 8209 PetscFunctionBegin; 8210 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8211 PetscValidType(mat,1); 8212 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8213 MatCheckPreallocated(mat,1); 8214 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8215 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8216 mat->nearnullsp = nullsp; 8217 PetscFunctionReturn(0); 8218 } 8219 8220 /*@ 8221 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8222 8223 Not Collective 8224 8225 Input Parameters: 8226 . mat - the matrix 8227 8228 Output Parameters: 8229 . nullsp - the null space object, NULL if not set 8230 8231 Level: developer 8232 8233 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8234 @*/ 8235 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8236 { 8237 PetscFunctionBegin; 8238 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8239 PetscValidType(mat,1); 8240 PetscValidPointer(nullsp,2); 8241 MatCheckPreallocated(mat,1); 8242 *nullsp = mat->nearnullsp; 8243 PetscFunctionReturn(0); 8244 } 8245 8246 /*@C 8247 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8248 8249 Collective on Mat 8250 8251 Input Parameters: 8252 + mat - the matrix 8253 . row - row/column permutation 8254 . fill - expected fill factor >= 1.0 8255 - level - level of fill, for ICC(k) 8256 8257 Notes: 8258 Probably really in-place only when level of fill is zero, otherwise allocates 8259 new space to store factored matrix and deletes previous memory. 8260 8261 Most users should employ the simplified KSP interface for linear solvers 8262 instead of working directly with matrix algebra routines such as this. 8263 See, e.g., KSPCreate(). 8264 8265 Level: developer 8266 8267 8268 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8269 8270 Developer Note: fortran interface is not autogenerated as the f90 8271 interface defintion cannot be generated correctly [due to MatFactorInfo] 8272 8273 @*/ 8274 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8275 { 8276 PetscErrorCode ierr; 8277 8278 PetscFunctionBegin; 8279 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8280 PetscValidType(mat,1); 8281 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8282 PetscValidPointer(info,3); 8283 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8284 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8285 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8286 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8287 MatCheckPreallocated(mat,1); 8288 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8289 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8290 PetscFunctionReturn(0); 8291 } 8292 8293 /*@ 8294 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8295 ghosted ones. 8296 8297 Not Collective 8298 8299 Input Parameters: 8300 + mat - the matrix 8301 - diag = the diagonal values, including ghost ones 8302 8303 Level: developer 8304 8305 Notes: 8306 Works only for MPIAIJ and MPIBAIJ matrices 8307 8308 .seealso: MatDiagonalScale() 8309 @*/ 8310 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8311 { 8312 PetscErrorCode ierr; 8313 PetscMPIInt size; 8314 8315 PetscFunctionBegin; 8316 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8317 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8318 PetscValidType(mat,1); 8319 8320 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8321 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8322 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8323 if (size == 1) { 8324 PetscInt n,m; 8325 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8326 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8327 if (m == n) { 8328 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8329 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8330 } else { 8331 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8332 } 8333 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8334 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8335 PetscFunctionReturn(0); 8336 } 8337 8338 /*@ 8339 MatGetInertia - Gets the inertia from a factored matrix 8340 8341 Collective on Mat 8342 8343 Input Parameter: 8344 . mat - the matrix 8345 8346 Output Parameters: 8347 + nneg - number of negative eigenvalues 8348 . nzero - number of zero eigenvalues 8349 - npos - number of positive eigenvalues 8350 8351 Level: advanced 8352 8353 Notes: 8354 Matrix must have been factored by MatCholeskyFactor() 8355 8356 8357 @*/ 8358 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8359 { 8360 PetscErrorCode ierr; 8361 8362 PetscFunctionBegin; 8363 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8364 PetscValidType(mat,1); 8365 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8366 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8367 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8368 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8369 PetscFunctionReturn(0); 8370 } 8371 8372 /* ----------------------------------------------------------------*/ 8373 /*@C 8374 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8375 8376 Neighbor-wise Collective on Mats 8377 8378 Input Parameters: 8379 + mat - the factored matrix 8380 - b - the right-hand-side vectors 8381 8382 Output Parameter: 8383 . x - the result vectors 8384 8385 Notes: 8386 The vectors b and x cannot be the same. I.e., one cannot 8387 call MatSolves(A,x,x). 8388 8389 Notes: 8390 Most users should employ the simplified KSP interface for linear solvers 8391 instead of working directly with matrix algebra routines such as this. 8392 See, e.g., KSPCreate(). 8393 8394 Level: developer 8395 8396 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8397 @*/ 8398 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8399 { 8400 PetscErrorCode ierr; 8401 8402 PetscFunctionBegin; 8403 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8404 PetscValidType(mat,1); 8405 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8406 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8407 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8408 8409 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8410 MatCheckPreallocated(mat,1); 8411 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8412 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8413 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8414 PetscFunctionReturn(0); 8415 } 8416 8417 /*@ 8418 MatIsSymmetric - Test whether a matrix is symmetric 8419 8420 Collective on Mat 8421 8422 Input Parameter: 8423 + A - the matrix to test 8424 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8425 8426 Output Parameters: 8427 . flg - the result 8428 8429 Notes: 8430 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8431 8432 Level: intermediate 8433 8434 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8435 @*/ 8436 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8437 { 8438 PetscErrorCode ierr; 8439 8440 PetscFunctionBegin; 8441 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8442 PetscValidBoolPointer(flg,2); 8443 8444 if (!A->symmetric_set) { 8445 if (!A->ops->issymmetric) { 8446 MatType mattype; 8447 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8448 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8449 } 8450 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8451 if (!tol) { 8452 A->symmetric_set = PETSC_TRUE; 8453 A->symmetric = *flg; 8454 if (A->symmetric) { 8455 A->structurally_symmetric_set = PETSC_TRUE; 8456 A->structurally_symmetric = PETSC_TRUE; 8457 } 8458 } 8459 } else if (A->symmetric) { 8460 *flg = PETSC_TRUE; 8461 } else if (!tol) { 8462 *flg = PETSC_FALSE; 8463 } else { 8464 if (!A->ops->issymmetric) { 8465 MatType mattype; 8466 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8467 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8468 } 8469 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8470 } 8471 PetscFunctionReturn(0); 8472 } 8473 8474 /*@ 8475 MatIsHermitian - Test whether a matrix is Hermitian 8476 8477 Collective on Mat 8478 8479 Input Parameter: 8480 + A - the matrix to test 8481 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8482 8483 Output Parameters: 8484 . flg - the result 8485 8486 Level: intermediate 8487 8488 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8489 MatIsSymmetricKnown(), MatIsSymmetric() 8490 @*/ 8491 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8492 { 8493 PetscErrorCode ierr; 8494 8495 PetscFunctionBegin; 8496 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8497 PetscValidBoolPointer(flg,2); 8498 8499 if (!A->hermitian_set) { 8500 if (!A->ops->ishermitian) { 8501 MatType mattype; 8502 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8503 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8504 } 8505 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8506 if (!tol) { 8507 A->hermitian_set = PETSC_TRUE; 8508 A->hermitian = *flg; 8509 if (A->hermitian) { 8510 A->structurally_symmetric_set = PETSC_TRUE; 8511 A->structurally_symmetric = PETSC_TRUE; 8512 } 8513 } 8514 } else if (A->hermitian) { 8515 *flg = PETSC_TRUE; 8516 } else if (!tol) { 8517 *flg = PETSC_FALSE; 8518 } else { 8519 if (!A->ops->ishermitian) { 8520 MatType mattype; 8521 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8522 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8523 } 8524 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8525 } 8526 PetscFunctionReturn(0); 8527 } 8528 8529 /*@ 8530 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8531 8532 Not Collective 8533 8534 Input Parameter: 8535 . A - the matrix to check 8536 8537 Output Parameters: 8538 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8539 - flg - the result 8540 8541 Level: advanced 8542 8543 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8544 if you want it explicitly checked 8545 8546 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8547 @*/ 8548 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8549 { 8550 PetscFunctionBegin; 8551 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8552 PetscValidPointer(set,2); 8553 PetscValidBoolPointer(flg,3); 8554 if (A->symmetric_set) { 8555 *set = PETSC_TRUE; 8556 *flg = A->symmetric; 8557 } else { 8558 *set = PETSC_FALSE; 8559 } 8560 PetscFunctionReturn(0); 8561 } 8562 8563 /*@ 8564 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8565 8566 Not Collective 8567 8568 Input Parameter: 8569 . A - the matrix to check 8570 8571 Output Parameters: 8572 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8573 - flg - the result 8574 8575 Level: advanced 8576 8577 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8578 if you want it explicitly checked 8579 8580 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8581 @*/ 8582 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8583 { 8584 PetscFunctionBegin; 8585 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8586 PetscValidPointer(set,2); 8587 PetscValidBoolPointer(flg,3); 8588 if (A->hermitian_set) { 8589 *set = PETSC_TRUE; 8590 *flg = A->hermitian; 8591 } else { 8592 *set = PETSC_FALSE; 8593 } 8594 PetscFunctionReturn(0); 8595 } 8596 8597 /*@ 8598 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8599 8600 Collective on Mat 8601 8602 Input Parameter: 8603 . A - the matrix to test 8604 8605 Output Parameters: 8606 . flg - the result 8607 8608 Level: intermediate 8609 8610 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8611 @*/ 8612 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8613 { 8614 PetscErrorCode ierr; 8615 8616 PetscFunctionBegin; 8617 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8618 PetscValidBoolPointer(flg,2); 8619 if (!A->structurally_symmetric_set) { 8620 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8621 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8622 8623 A->structurally_symmetric_set = PETSC_TRUE; 8624 } 8625 *flg = A->structurally_symmetric; 8626 PetscFunctionReturn(0); 8627 } 8628 8629 /*@ 8630 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8631 to be communicated to other processors during the MatAssemblyBegin/End() process 8632 8633 Not collective 8634 8635 Input Parameter: 8636 . vec - the vector 8637 8638 Output Parameters: 8639 + nstash - the size of the stash 8640 . reallocs - the number of additional mallocs incurred. 8641 . bnstash - the size of the block stash 8642 - breallocs - the number of additional mallocs incurred.in the block stash 8643 8644 Level: advanced 8645 8646 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8647 8648 @*/ 8649 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8650 { 8651 PetscErrorCode ierr; 8652 8653 PetscFunctionBegin; 8654 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8655 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8656 PetscFunctionReturn(0); 8657 } 8658 8659 /*@C 8660 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8661 parallel layout 8662 8663 Collective on Mat 8664 8665 Input Parameter: 8666 . mat - the matrix 8667 8668 Output Parameter: 8669 + right - (optional) vector that the matrix can be multiplied against 8670 - left - (optional) vector that the matrix vector product can be stored in 8671 8672 Notes: 8673 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(). 8674 8675 Notes: 8676 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8677 8678 Level: advanced 8679 8680 .seealso: MatCreate(), VecDestroy() 8681 @*/ 8682 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8683 { 8684 PetscErrorCode ierr; 8685 8686 PetscFunctionBegin; 8687 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8688 PetscValidType(mat,1); 8689 if (mat->ops->getvecs) { 8690 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8691 } else { 8692 PetscInt rbs,cbs; 8693 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8694 if (right) { 8695 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8696 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8697 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8698 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8699 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 8700 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8701 } 8702 if (left) { 8703 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8704 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8705 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8706 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8707 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 8708 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8709 } 8710 } 8711 PetscFunctionReturn(0); 8712 } 8713 8714 /*@C 8715 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8716 with default values. 8717 8718 Not Collective 8719 8720 Input Parameters: 8721 . info - the MatFactorInfo data structure 8722 8723 8724 Notes: 8725 The solvers are generally used through the KSP and PC objects, for example 8726 PCLU, PCILU, PCCHOLESKY, PCICC 8727 8728 Level: developer 8729 8730 .seealso: MatFactorInfo 8731 8732 Developer Note: fortran interface is not autogenerated as the f90 8733 interface defintion cannot be generated correctly [due to MatFactorInfo] 8734 8735 @*/ 8736 8737 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8738 { 8739 PetscErrorCode ierr; 8740 8741 PetscFunctionBegin; 8742 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8743 PetscFunctionReturn(0); 8744 } 8745 8746 /*@ 8747 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 8748 8749 Collective on Mat 8750 8751 Input Parameters: 8752 + mat - the factored matrix 8753 - is - the index set defining the Schur indices (0-based) 8754 8755 Notes: 8756 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 8757 8758 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 8759 8760 Level: developer 8761 8762 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 8763 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 8764 8765 @*/ 8766 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 8767 { 8768 PetscErrorCode ierr,(*f)(Mat,IS); 8769 8770 PetscFunctionBegin; 8771 PetscValidType(mat,1); 8772 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8773 PetscValidType(is,2); 8774 PetscValidHeaderSpecific(is,IS_CLASSID,2); 8775 PetscCheckSameComm(mat,1,is,2); 8776 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 8777 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 8778 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"); 8779 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 8780 ierr = (*f)(mat,is);CHKERRQ(ierr); 8781 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 8782 PetscFunctionReturn(0); 8783 } 8784 8785 /*@ 8786 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 8787 8788 Logically Collective on Mat 8789 8790 Input Parameters: 8791 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 8792 . S - location where to return the Schur complement, can be NULL 8793 - status - the status of the Schur complement matrix, can be NULL 8794 8795 Notes: 8796 You must call MatFactorSetSchurIS() before calling this routine. 8797 8798 The routine provides a copy of the Schur matrix stored within the solver data structures. 8799 The caller must destroy the object when it is no longer needed. 8800 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 8801 8802 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) 8803 8804 Developer Notes: 8805 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 8806 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 8807 8808 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 8809 8810 Level: advanced 8811 8812 References: 8813 8814 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 8815 @*/ 8816 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 8817 { 8818 PetscErrorCode ierr; 8819 8820 PetscFunctionBegin; 8821 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8822 if (S) PetscValidPointer(S,2); 8823 if (status) PetscValidPointer(status,3); 8824 if (S) { 8825 PetscErrorCode (*f)(Mat,Mat*); 8826 8827 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 8828 if (f) { 8829 ierr = (*f)(F,S);CHKERRQ(ierr); 8830 } else { 8831 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 8832 } 8833 } 8834 if (status) *status = F->schur_status; 8835 PetscFunctionReturn(0); 8836 } 8837 8838 /*@ 8839 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 8840 8841 Logically Collective on Mat 8842 8843 Input Parameters: 8844 + F - the factored matrix obtained by calling MatGetFactor() 8845 . *S - location where to return the Schur complement, can be NULL 8846 - status - the status of the Schur complement matrix, can be NULL 8847 8848 Notes: 8849 You must call MatFactorSetSchurIS() before calling this routine. 8850 8851 Schur complement mode is currently implemented for sequential matrices. 8852 The routine returns a the Schur Complement stored within the data strutures of the solver. 8853 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 8854 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 8855 8856 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 8857 8858 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 8859 8860 Level: advanced 8861 8862 References: 8863 8864 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 8865 @*/ 8866 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 8867 { 8868 PetscFunctionBegin; 8869 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8870 if (S) PetscValidPointer(S,2); 8871 if (status) PetscValidPointer(status,3); 8872 if (S) *S = F->schur; 8873 if (status) *status = F->schur_status; 8874 PetscFunctionReturn(0); 8875 } 8876 8877 /*@ 8878 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 8879 8880 Logically Collective on Mat 8881 8882 Input Parameters: 8883 + F - the factored matrix obtained by calling MatGetFactor() 8884 . *S - location where the Schur complement is stored 8885 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 8886 8887 Notes: 8888 8889 Level: advanced 8890 8891 References: 8892 8893 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 8894 @*/ 8895 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 8896 { 8897 PetscErrorCode ierr; 8898 8899 PetscFunctionBegin; 8900 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8901 if (S) { 8902 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 8903 *S = NULL; 8904 } 8905 F->schur_status = status; 8906 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 8907 PetscFunctionReturn(0); 8908 } 8909 8910 /*@ 8911 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 8912 8913 Logically Collective on Mat 8914 8915 Input Parameters: 8916 + F - the factored matrix obtained by calling MatGetFactor() 8917 . rhs - location where the right hand side of the Schur complement system is stored 8918 - sol - location where the solution of the Schur complement system has to be returned 8919 8920 Notes: 8921 The sizes of the vectors should match the size of the Schur complement 8922 8923 Must be called after MatFactorSetSchurIS() 8924 8925 Level: advanced 8926 8927 References: 8928 8929 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 8930 @*/ 8931 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 8932 { 8933 PetscErrorCode ierr; 8934 8935 PetscFunctionBegin; 8936 PetscValidType(F,1); 8937 PetscValidType(rhs,2); 8938 PetscValidType(sol,3); 8939 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8940 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 8941 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 8942 PetscCheckSameComm(F,1,rhs,2); 8943 PetscCheckSameComm(F,1,sol,3); 8944 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 8945 switch (F->schur_status) { 8946 case MAT_FACTOR_SCHUR_FACTORED: 8947 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 8948 break; 8949 case MAT_FACTOR_SCHUR_INVERTED: 8950 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 8951 break; 8952 default: 8953 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 8954 break; 8955 } 8956 PetscFunctionReturn(0); 8957 } 8958 8959 /*@ 8960 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 8961 8962 Logically Collective on Mat 8963 8964 Input Parameters: 8965 + F - the factored matrix obtained by calling MatGetFactor() 8966 . rhs - location where the right hand side of the Schur complement system is stored 8967 - sol - location where the solution of the Schur complement system has to be returned 8968 8969 Notes: 8970 The sizes of the vectors should match the size of the Schur complement 8971 8972 Must be called after MatFactorSetSchurIS() 8973 8974 Level: advanced 8975 8976 References: 8977 8978 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 8979 @*/ 8980 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 8981 { 8982 PetscErrorCode ierr; 8983 8984 PetscFunctionBegin; 8985 PetscValidType(F,1); 8986 PetscValidType(rhs,2); 8987 PetscValidType(sol,3); 8988 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8989 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 8990 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 8991 PetscCheckSameComm(F,1,rhs,2); 8992 PetscCheckSameComm(F,1,sol,3); 8993 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 8994 switch (F->schur_status) { 8995 case MAT_FACTOR_SCHUR_FACTORED: 8996 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 8997 break; 8998 case MAT_FACTOR_SCHUR_INVERTED: 8999 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 9000 break; 9001 default: 9002 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9003 break; 9004 } 9005 PetscFunctionReturn(0); 9006 } 9007 9008 /*@ 9009 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9010 9011 Logically Collective on Mat 9012 9013 Input Parameters: 9014 . F - the factored matrix obtained by calling MatGetFactor() 9015 9016 Notes: 9017 Must be called after MatFactorSetSchurIS(). 9018 9019 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9020 9021 Level: advanced 9022 9023 References: 9024 9025 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9026 @*/ 9027 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9028 { 9029 PetscErrorCode ierr; 9030 9031 PetscFunctionBegin; 9032 PetscValidType(F,1); 9033 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9034 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9035 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9036 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9037 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9038 PetscFunctionReturn(0); 9039 } 9040 9041 /*@ 9042 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9043 9044 Logically Collective on Mat 9045 9046 Input Parameters: 9047 . F - the factored matrix obtained by calling MatGetFactor() 9048 9049 Notes: 9050 Must be called after MatFactorSetSchurIS(). 9051 9052 Level: advanced 9053 9054 References: 9055 9056 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9057 @*/ 9058 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9059 { 9060 PetscErrorCode ierr; 9061 9062 PetscFunctionBegin; 9063 PetscValidType(F,1); 9064 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9065 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9066 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9067 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9068 PetscFunctionReturn(0); 9069 } 9070 9071 PetscErrorCode MatPtAP_Basic(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9072 { 9073 Mat AP; 9074 PetscErrorCode ierr; 9075 9076 PetscFunctionBegin; 9077 ierr = PetscInfo2(A,"Mat types %s and %s using basic PtAP\n",((PetscObject)A)->type_name,((PetscObject)P)->type_name);CHKERRQ(ierr); 9078 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AP);CHKERRQ(ierr); 9079 ierr = MatTransposeMatMult(P,AP,scall,fill,C);CHKERRQ(ierr); 9080 ierr = MatDestroy(&AP);CHKERRQ(ierr); 9081 PetscFunctionReturn(0); 9082 } 9083 9084 /*@ 9085 MatPtAP - Creates the matrix product C = P^T * A * P 9086 9087 Neighbor-wise Collective on Mat 9088 9089 Input Parameters: 9090 + A - the matrix 9091 . P - the projection matrix 9092 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9093 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9094 if the result is a dense matrix this is irrelevent 9095 9096 Output Parameters: 9097 . C - the product matrix 9098 9099 Notes: 9100 C will be created and must be destroyed by the user with MatDestroy(). 9101 9102 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9103 9104 Level: intermediate 9105 9106 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9107 @*/ 9108 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9109 { 9110 PetscErrorCode ierr; 9111 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9112 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9113 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9114 PetscBool sametype; 9115 9116 PetscFunctionBegin; 9117 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9118 PetscValidType(A,1); 9119 MatCheckPreallocated(A,1); 9120 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9121 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9122 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9123 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9124 PetscValidType(P,2); 9125 MatCheckPreallocated(P,2); 9126 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9127 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9128 9129 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); 9130 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); 9131 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9132 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9133 9134 if (scall == MAT_REUSE_MATRIX) { 9135 PetscValidPointer(*C,5); 9136 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9137 9138 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9139 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9140 if ((*C)->ops->ptapnumeric) { 9141 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9142 } else { 9143 ierr = MatPtAP_Basic(A,P,scall,fill,C); 9144 } 9145 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9146 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9147 PetscFunctionReturn(0); 9148 } 9149 9150 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9151 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9152 9153 fA = A->ops->ptap; 9154 fP = P->ops->ptap; 9155 ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr); 9156 if (fP == fA && sametype) { 9157 ptap = fA; 9158 } else { 9159 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9160 char ptapname[256]; 9161 ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr); 9162 ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9163 ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr); 9164 ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9165 ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9166 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9167 } 9168 9169 if (!ptap) ptap = MatPtAP_Basic; 9170 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9171 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9172 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9173 if (A->symmetric_set && A->symmetric) { 9174 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9175 } 9176 PetscFunctionReturn(0); 9177 } 9178 9179 /*@ 9180 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9181 9182 Neighbor-wise Collective on Mat 9183 9184 Input Parameters: 9185 + A - the matrix 9186 - P - the projection matrix 9187 9188 Output Parameters: 9189 . C - the product matrix 9190 9191 Notes: 9192 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9193 the user using MatDeatroy(). 9194 9195 This routine is currently only implemented for pairs of AIJ matrices and classes 9196 which inherit from AIJ. C will be of type MATAIJ. 9197 9198 Level: intermediate 9199 9200 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9201 @*/ 9202 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9203 { 9204 PetscErrorCode ierr; 9205 9206 PetscFunctionBegin; 9207 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9208 PetscValidType(A,1); 9209 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9210 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9211 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9212 PetscValidType(P,2); 9213 MatCheckPreallocated(P,2); 9214 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9215 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9216 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9217 PetscValidType(C,3); 9218 MatCheckPreallocated(C,3); 9219 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9220 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); 9221 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); 9222 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); 9223 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); 9224 MatCheckPreallocated(A,1); 9225 9226 if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first"); 9227 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9228 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9229 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9230 PetscFunctionReturn(0); 9231 } 9232 9233 /*@ 9234 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9235 9236 Neighbor-wise Collective on Mat 9237 9238 Input Parameters: 9239 + A - the matrix 9240 - P - the projection matrix 9241 9242 Output Parameters: 9243 . C - the (i,j) structure of the product matrix 9244 9245 Notes: 9246 C will be created and must be destroyed by the user with MatDestroy(). 9247 9248 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9249 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9250 this (i,j) structure by calling MatPtAPNumeric(). 9251 9252 Level: intermediate 9253 9254 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9255 @*/ 9256 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9257 { 9258 PetscErrorCode ierr; 9259 9260 PetscFunctionBegin; 9261 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9262 PetscValidType(A,1); 9263 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9264 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9265 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9266 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9267 PetscValidType(P,2); 9268 MatCheckPreallocated(P,2); 9269 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9270 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9271 PetscValidPointer(C,3); 9272 9273 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); 9274 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); 9275 MatCheckPreallocated(A,1); 9276 9277 if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name); 9278 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9279 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9280 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9281 9282 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9283 PetscFunctionReturn(0); 9284 } 9285 9286 /*@ 9287 MatRARt - Creates the matrix product C = R * A * R^T 9288 9289 Neighbor-wise Collective on Mat 9290 9291 Input Parameters: 9292 + A - the matrix 9293 . R - the projection matrix 9294 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9295 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9296 if the result is a dense matrix this is irrelevent 9297 9298 Output Parameters: 9299 . C - the product matrix 9300 9301 Notes: 9302 C will be created and must be destroyed by the user with MatDestroy(). 9303 9304 This routine is currently only implemented for pairs of AIJ matrices and classes 9305 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9306 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9307 We recommend using MatPtAP(). 9308 9309 Level: intermediate 9310 9311 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9312 @*/ 9313 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9314 { 9315 PetscErrorCode ierr; 9316 9317 PetscFunctionBegin; 9318 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9319 PetscValidType(A,1); 9320 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9321 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9322 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9323 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9324 PetscValidType(R,2); 9325 MatCheckPreallocated(R,2); 9326 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9327 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9328 PetscValidPointer(C,3); 9329 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); 9330 9331 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9332 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9333 MatCheckPreallocated(A,1); 9334 9335 if (!A->ops->rart) { 9336 Mat Rt; 9337 ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 9338 ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr); 9339 ierr = MatDestroy(&Rt);CHKERRQ(ierr); 9340 PetscFunctionReturn(0); 9341 } 9342 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9343 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9344 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9345 PetscFunctionReturn(0); 9346 } 9347 9348 /*@ 9349 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9350 9351 Neighbor-wise Collective on Mat 9352 9353 Input Parameters: 9354 + A - the matrix 9355 - R - the projection matrix 9356 9357 Output Parameters: 9358 . C - the product matrix 9359 9360 Notes: 9361 C must have been created by calling MatRARtSymbolic and must be destroyed by 9362 the user using MatDestroy(). 9363 9364 This routine is currently only implemented for pairs of AIJ matrices and classes 9365 which inherit from AIJ. C will be of type MATAIJ. 9366 9367 Level: intermediate 9368 9369 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9370 @*/ 9371 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9372 { 9373 PetscErrorCode ierr; 9374 9375 PetscFunctionBegin; 9376 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9377 PetscValidType(A,1); 9378 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9379 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9380 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9381 PetscValidType(R,2); 9382 MatCheckPreallocated(R,2); 9383 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9384 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9385 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9386 PetscValidType(C,3); 9387 MatCheckPreallocated(C,3); 9388 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9389 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); 9390 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); 9391 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); 9392 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); 9393 MatCheckPreallocated(A,1); 9394 9395 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9396 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9397 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9398 PetscFunctionReturn(0); 9399 } 9400 9401 /*@ 9402 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9403 9404 Neighbor-wise Collective on Mat 9405 9406 Input Parameters: 9407 + A - the matrix 9408 - R - the projection matrix 9409 9410 Output Parameters: 9411 . C - the (i,j) structure of the product matrix 9412 9413 Notes: 9414 C will be created and must be destroyed by the user with MatDestroy(). 9415 9416 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9417 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9418 this (i,j) structure by calling MatRARtNumeric(). 9419 9420 Level: intermediate 9421 9422 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9423 @*/ 9424 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9425 { 9426 PetscErrorCode ierr; 9427 9428 PetscFunctionBegin; 9429 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9430 PetscValidType(A,1); 9431 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9432 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9433 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9434 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9435 PetscValidType(R,2); 9436 MatCheckPreallocated(R,2); 9437 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9438 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9439 PetscValidPointer(C,3); 9440 9441 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); 9442 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); 9443 MatCheckPreallocated(A,1); 9444 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9445 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9446 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9447 9448 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9449 PetscFunctionReturn(0); 9450 } 9451 9452 /*@ 9453 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9454 9455 Neighbor-wise Collective on Mat 9456 9457 Input Parameters: 9458 + A - the left matrix 9459 . B - the right matrix 9460 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9461 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9462 if the result is a dense matrix this is irrelevent 9463 9464 Output Parameters: 9465 . C - the product matrix 9466 9467 Notes: 9468 Unless scall is MAT_REUSE_MATRIX C will be created. 9469 9470 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 9471 call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic() 9472 9473 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9474 actually needed. 9475 9476 If you have many matrices with the same non-zero structure to multiply, you 9477 should either 9478 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9479 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9480 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 9481 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9482 9483 Level: intermediate 9484 9485 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9486 @*/ 9487 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9488 { 9489 PetscErrorCode ierr; 9490 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9491 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9492 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9493 Mat T; 9494 PetscBool istrans; 9495 9496 PetscFunctionBegin; 9497 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9498 PetscValidType(A,1); 9499 MatCheckPreallocated(A,1); 9500 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9501 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9502 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9503 PetscValidType(B,2); 9504 MatCheckPreallocated(B,2); 9505 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9506 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9507 PetscValidPointer(C,3); 9508 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9509 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); 9510 ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9511 if (istrans) { 9512 ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 9513 ierr = MatTransposeMatMult(T,B,scall,fill,C);CHKERRQ(ierr); 9514 PetscFunctionReturn(0); 9515 } else { 9516 ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9517 if (istrans) { 9518 ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr); 9519 ierr = MatMatTransposeMult(A,T,scall,fill,C);CHKERRQ(ierr); 9520 PetscFunctionReturn(0); 9521 } 9522 } 9523 if (scall == MAT_REUSE_MATRIX) { 9524 PetscValidPointer(*C,5); 9525 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9526 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9527 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9528 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9529 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9530 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9531 PetscFunctionReturn(0); 9532 } 9533 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9534 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9535 9536 fA = A->ops->matmult; 9537 fB = B->ops->matmult; 9538 if (fB == fA && fB) mult = fB; 9539 else { 9540 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9541 char multname[256]; 9542 ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr); 9543 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9544 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9545 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9546 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9547 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9548 if (!mult) { 9549 ierr = PetscObjectQueryFunction((PetscObject)A,multname,&mult);CHKERRQ(ierr); 9550 } 9551 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); 9552 } 9553 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9554 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9555 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9556 PetscFunctionReturn(0); 9557 } 9558 9559 /*@ 9560 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9561 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9562 9563 Neighbor-wise Collective on Mat 9564 9565 Input Parameters: 9566 + A - the left matrix 9567 . B - the right matrix 9568 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9569 if C is a dense matrix this is irrelevent 9570 9571 Output Parameters: 9572 . C - the product matrix 9573 9574 Notes: 9575 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9576 actually needed. 9577 9578 This routine is currently implemented for 9579 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9580 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9581 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9582 9583 Level: intermediate 9584 9585 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, https://arxiv.org/abs/1006.4173 9586 We should incorporate them into PETSc. 9587 9588 .seealso: MatMatMult(), MatMatMultNumeric() 9589 @*/ 9590 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9591 { 9592 PetscErrorCode ierr; 9593 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9594 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9595 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9596 9597 PetscFunctionBegin; 9598 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9599 PetscValidType(A,1); 9600 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9601 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9602 9603 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9604 PetscValidType(B,2); 9605 MatCheckPreallocated(B,2); 9606 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9607 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9608 PetscValidPointer(C,3); 9609 9610 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); 9611 if (fill == PETSC_DEFAULT) fill = 2.0; 9612 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9613 MatCheckPreallocated(A,1); 9614 9615 Asymbolic = A->ops->matmultsymbolic; 9616 Bsymbolic = B->ops->matmultsymbolic; 9617 if (Asymbolic == Bsymbolic) { 9618 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 9619 symbolic = Bsymbolic; 9620 } else { /* dispatch based on the type of A and B */ 9621 char symbolicname[256]; 9622 ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9623 ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9624 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9625 ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9626 ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr); 9627 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9628 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); 9629 } 9630 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9631 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 9632 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9633 PetscFunctionReturn(0); 9634 } 9635 9636 /*@ 9637 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9638 Call this routine after first calling MatMatMultSymbolic(). 9639 9640 Neighbor-wise Collective on Mat 9641 9642 Input Parameters: 9643 + A - the left matrix 9644 - B - the right matrix 9645 9646 Output Parameters: 9647 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9648 9649 Notes: 9650 C must have been created with MatMatMultSymbolic(). 9651 9652 This routine is currently implemented for 9653 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9654 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9655 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9656 9657 Level: intermediate 9658 9659 .seealso: MatMatMult(), MatMatMultSymbolic() 9660 @*/ 9661 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9662 { 9663 PetscErrorCode ierr; 9664 9665 PetscFunctionBegin; 9666 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 9667 PetscFunctionReturn(0); 9668 } 9669 9670 /*@ 9671 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9672 9673 Neighbor-wise Collective on Mat 9674 9675 Input Parameters: 9676 + A - the left matrix 9677 . B - the right matrix 9678 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9679 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9680 9681 Output Parameters: 9682 . C - the product matrix 9683 9684 Notes: 9685 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9686 9687 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9688 9689 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9690 actually needed. 9691 9692 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9693 and for pairs of MPIDense matrices. 9694 9695 Options Database Keys: 9696 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the 9697 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9698 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9699 9700 Level: intermediate 9701 9702 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9703 @*/ 9704 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9705 { 9706 PetscErrorCode ierr; 9707 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9708 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9709 Mat T; 9710 PetscBool istrans; 9711 9712 PetscFunctionBegin; 9713 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9714 PetscValidType(A,1); 9715 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9716 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9717 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9718 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9719 PetscValidType(B,2); 9720 MatCheckPreallocated(B,2); 9721 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9722 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9723 PetscValidPointer(C,3); 9724 if (B->cmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, AN %D != BN %D",A->cmap->N,B->cmap->N); 9725 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9726 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9727 MatCheckPreallocated(A,1); 9728 9729 ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9730 if (istrans) { 9731 ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr); 9732 ierr = MatMatMult(A,T,scall,fill,C);CHKERRQ(ierr); 9733 PetscFunctionReturn(0); 9734 } 9735 fA = A->ops->mattransposemult; 9736 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9737 fB = B->ops->mattransposemult; 9738 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9739 if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9740 9741 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9742 if (scall == MAT_INITIAL_MATRIX) { 9743 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9744 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9745 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9746 } 9747 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9748 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 9749 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9750 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9751 PetscFunctionReturn(0); 9752 } 9753 9754 /*@ 9755 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9756 9757 Neighbor-wise Collective on Mat 9758 9759 Input Parameters: 9760 + A - the left matrix 9761 . B - the right matrix 9762 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9763 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9764 9765 Output Parameters: 9766 . C - the product matrix 9767 9768 Notes: 9769 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9770 9771 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9772 9773 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9774 actually needed. 9775 9776 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9777 which inherit from SeqAIJ. C will be of same type as the input matrices. 9778 9779 Level: intermediate 9780 9781 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 9782 @*/ 9783 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9784 { 9785 PetscErrorCode ierr; 9786 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9787 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9788 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 9789 Mat T; 9790 PetscBool istrans; 9791 9792 PetscFunctionBegin; 9793 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9794 PetscValidType(A,1); 9795 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9796 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9797 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9798 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9799 PetscValidType(B,2); 9800 MatCheckPreallocated(B,2); 9801 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9802 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9803 PetscValidPointer(C,3); 9804 if (B->rmap->N!=A->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->rmap->N); 9805 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9806 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9807 MatCheckPreallocated(A,1); 9808 9809 ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9810 if (istrans) { 9811 ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 9812 ierr = MatMatMult(T,B,scall,fill,C);CHKERRQ(ierr); 9813 PetscFunctionReturn(0); 9814 } 9815 fA = A->ops->transposematmult; 9816 fB = B->ops->transposematmult; 9817 if (fB == fA && fA) transposematmult = fA; 9818 else { 9819 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9820 char multname[256]; 9821 ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr); 9822 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9823 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9824 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9825 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9826 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 9827 if (!transposematmult) { 9828 ierr = PetscObjectQueryFunction((PetscObject)A,multname,&transposematmult);CHKERRQ(ierr); 9829 } 9830 if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name); 9831 } 9832 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9833 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 9834 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9835 PetscFunctionReturn(0); 9836 } 9837 9838 /*@ 9839 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9840 9841 Neighbor-wise Collective on Mat 9842 9843 Input Parameters: 9844 + A - the left matrix 9845 . B - the middle matrix 9846 . C - the right matrix 9847 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9848 - fill - expected fill as ratio of nnz(D)/(nnz(A) + nnz(B)+nnz(C)), use PETSC_DEFAULT if you do not have a good estimate 9849 if the result is a dense matrix this is irrelevent 9850 9851 Output Parameters: 9852 . D - the product matrix 9853 9854 Notes: 9855 Unless scall is MAT_REUSE_MATRIX D will be created. 9856 9857 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9858 9859 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9860 actually needed. 9861 9862 If you have many matrices with the same non-zero structure to multiply, you 9863 should use MAT_REUSE_MATRIX in all calls but the first or 9864 9865 Level: intermediate 9866 9867 .seealso: MatMatMult, MatPtAP() 9868 @*/ 9869 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9870 { 9871 PetscErrorCode ierr; 9872 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9873 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9874 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9875 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9876 9877 PetscFunctionBegin; 9878 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9879 PetscValidType(A,1); 9880 MatCheckPreallocated(A,1); 9881 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9882 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9883 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9884 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9885 PetscValidType(B,2); 9886 MatCheckPreallocated(B,2); 9887 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9888 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9889 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9890 PetscValidPointer(C,3); 9891 MatCheckPreallocated(C,3); 9892 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9893 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9894 if (B->rmap->N!=A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",B->rmap->N,A->cmap->N); 9895 if (C->rmap->N!=B->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_SIZ,"Matrix dimensions are incompatible, %D != %D",C->rmap->N,B->cmap->N); 9896 if (scall == MAT_REUSE_MATRIX) { 9897 PetscValidPointer(*D,6); 9898 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 9899 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9900 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9901 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9902 PetscFunctionReturn(0); 9903 } 9904 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9905 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9906 9907 fA = A->ops->matmatmult; 9908 fB = B->ops->matmatmult; 9909 fC = C->ops->matmatmult; 9910 if (fA == fB && fA == fC) { 9911 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9912 mult = fA; 9913 } else { 9914 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 9915 char multname[256]; 9916 ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr); 9917 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9918 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9919 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9920 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9921 ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr); 9922 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); 9923 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9924 if (!mult) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatMatMult requires A, %s, to be compatible with B, %s, C, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name,((PetscObject)C)->type_name); 9925 } 9926 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9927 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9928 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9929 PetscFunctionReturn(0); 9930 } 9931 9932 /*@ 9933 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9934 9935 Collective on Mat 9936 9937 Input Parameters: 9938 + mat - the matrix 9939 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9940 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 9941 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9942 9943 Output Parameter: 9944 . matredundant - redundant matrix 9945 9946 Notes: 9947 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9948 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9949 9950 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 9951 calling it. 9952 9953 Level: advanced 9954 9955 9956 .seealso: MatDestroy() 9957 @*/ 9958 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 9959 { 9960 PetscErrorCode ierr; 9961 MPI_Comm comm; 9962 PetscMPIInt size; 9963 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 9964 Mat_Redundant *redund=NULL; 9965 PetscSubcomm psubcomm=NULL; 9966 MPI_Comm subcomm_in=subcomm; 9967 Mat *matseq; 9968 IS isrow,iscol; 9969 PetscBool newsubcomm=PETSC_FALSE; 9970 9971 PetscFunctionBegin; 9972 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9973 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 9974 PetscValidPointer(*matredundant,5); 9975 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 9976 } 9977 9978 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 9979 if (size == 1 || nsubcomm == 1) { 9980 if (reuse == MAT_INITIAL_MATRIX) { 9981 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 9982 } else { 9983 if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 9984 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 9985 } 9986 PetscFunctionReturn(0); 9987 } 9988 9989 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9990 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9991 MatCheckPreallocated(mat,1); 9992 9993 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 9994 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 9995 /* create psubcomm, then get subcomm */ 9996 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 9997 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 9998 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 9999 10000 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10001 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10002 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10003 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10004 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10005 newsubcomm = PETSC_TRUE; 10006 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10007 } 10008 10009 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10010 if (reuse == MAT_INITIAL_MATRIX) { 10011 mloc_sub = PETSC_DECIDE; 10012 nloc_sub = PETSC_DECIDE; 10013 if (bs < 1) { 10014 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10015 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 10016 } else { 10017 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10018 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 10019 } 10020 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10021 rstart = rend - mloc_sub; 10022 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10023 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10024 } else { /* reuse == MAT_REUSE_MATRIX */ 10025 if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10026 /* retrieve subcomm */ 10027 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10028 redund = (*matredundant)->redundant; 10029 isrow = redund->isrow; 10030 iscol = redund->iscol; 10031 matseq = redund->matseq; 10032 } 10033 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10034 10035 /* get matredundant over subcomm */ 10036 if (reuse == MAT_INITIAL_MATRIX) { 10037 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 10038 10039 /* create a supporting struct and attach it to C for reuse */ 10040 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10041 (*matredundant)->redundant = redund; 10042 redund->isrow = isrow; 10043 redund->iscol = iscol; 10044 redund->matseq = matseq; 10045 if (newsubcomm) { 10046 redund->subcomm = subcomm; 10047 } else { 10048 redund->subcomm = MPI_COMM_NULL; 10049 } 10050 } else { 10051 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10052 } 10053 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10054 PetscFunctionReturn(0); 10055 } 10056 10057 /*@C 10058 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10059 a given 'mat' object. Each submatrix can span multiple procs. 10060 10061 Collective on Mat 10062 10063 Input Parameters: 10064 + mat - the matrix 10065 . subcomm - the subcommunicator obtained by com_split(comm) 10066 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10067 10068 Output Parameter: 10069 . subMat - 'parallel submatrices each spans a given subcomm 10070 10071 Notes: 10072 The submatrix partition across processors is dictated by 'subComm' a 10073 communicator obtained by com_split(comm). The comm_split 10074 is not restriced to be grouped with consecutive original ranks. 10075 10076 Due the comm_split() usage, the parallel layout of the submatrices 10077 map directly to the layout of the original matrix [wrt the local 10078 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10079 into the 'DiagonalMat' of the subMat, hence it is used directly from 10080 the subMat. However the offDiagMat looses some columns - and this is 10081 reconstructed with MatSetValues() 10082 10083 Level: advanced 10084 10085 10086 .seealso: MatCreateSubMatrices() 10087 @*/ 10088 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10089 { 10090 PetscErrorCode ierr; 10091 PetscMPIInt commsize,subCommSize; 10092 10093 PetscFunctionBegin; 10094 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10095 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10096 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10097 10098 if (scall == MAT_REUSE_MATRIX && *subMat == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10099 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10100 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10101 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10102 PetscFunctionReturn(0); 10103 } 10104 10105 /*@ 10106 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10107 10108 Not Collective 10109 10110 Input Arguments: 10111 + mat - matrix to extract local submatrix from 10112 . isrow - local row indices for submatrix 10113 - iscol - local column indices for submatrix 10114 10115 Output Arguments: 10116 . submat - the submatrix 10117 10118 Level: intermediate 10119 10120 Notes: 10121 The submat should be returned with MatRestoreLocalSubMatrix(). 10122 10123 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10124 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10125 10126 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10127 MatSetValuesBlockedLocal() will also be implemented. 10128 10129 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10130 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10131 10132 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10133 @*/ 10134 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10135 { 10136 PetscErrorCode ierr; 10137 10138 PetscFunctionBegin; 10139 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10140 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10141 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10142 PetscCheckSameComm(isrow,2,iscol,3); 10143 PetscValidPointer(submat,4); 10144 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10145 10146 if (mat->ops->getlocalsubmatrix) { 10147 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10148 } else { 10149 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10150 } 10151 PetscFunctionReturn(0); 10152 } 10153 10154 /*@ 10155 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10156 10157 Not Collective 10158 10159 Input Arguments: 10160 mat - matrix to extract local submatrix from 10161 isrow - local row indices for submatrix 10162 iscol - local column indices for submatrix 10163 submat - the submatrix 10164 10165 Level: intermediate 10166 10167 .seealso: MatGetLocalSubMatrix() 10168 @*/ 10169 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10170 { 10171 PetscErrorCode ierr; 10172 10173 PetscFunctionBegin; 10174 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10175 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10176 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10177 PetscCheckSameComm(isrow,2,iscol,3); 10178 PetscValidPointer(submat,4); 10179 if (*submat) { 10180 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10181 } 10182 10183 if (mat->ops->restorelocalsubmatrix) { 10184 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10185 } else { 10186 ierr = MatDestroy(submat);CHKERRQ(ierr); 10187 } 10188 *submat = NULL; 10189 PetscFunctionReturn(0); 10190 } 10191 10192 /* --------------------------------------------------------*/ 10193 /*@ 10194 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10195 10196 Collective on Mat 10197 10198 Input Parameter: 10199 . mat - the matrix 10200 10201 Output Parameter: 10202 . is - if any rows have zero diagonals this contains the list of them 10203 10204 Level: developer 10205 10206 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10207 @*/ 10208 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10209 { 10210 PetscErrorCode ierr; 10211 10212 PetscFunctionBegin; 10213 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10214 PetscValidType(mat,1); 10215 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10216 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10217 10218 if (!mat->ops->findzerodiagonals) { 10219 Vec diag; 10220 const PetscScalar *a; 10221 PetscInt *rows; 10222 PetscInt rStart, rEnd, r, nrow = 0; 10223 10224 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10225 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10226 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10227 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10228 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10229 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10230 nrow = 0; 10231 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10232 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10233 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10234 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10235 } else { 10236 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10237 } 10238 PetscFunctionReturn(0); 10239 } 10240 10241 /*@ 10242 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10243 10244 Collective on Mat 10245 10246 Input Parameter: 10247 . mat - the matrix 10248 10249 Output Parameter: 10250 . is - contains the list of rows with off block diagonal entries 10251 10252 Level: developer 10253 10254 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10255 @*/ 10256 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10257 { 10258 PetscErrorCode ierr; 10259 10260 PetscFunctionBegin; 10261 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10262 PetscValidType(mat,1); 10263 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10264 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10265 10266 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10267 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10268 PetscFunctionReturn(0); 10269 } 10270 10271 /*@C 10272 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10273 10274 Collective on Mat 10275 10276 Input Parameters: 10277 . mat - the matrix 10278 10279 Output Parameters: 10280 . values - the block inverses in column major order (FORTRAN-like) 10281 10282 Note: 10283 This routine is not available from Fortran. 10284 10285 Level: advanced 10286 10287 .seealso: MatInvertBockDiagonalMat 10288 @*/ 10289 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10290 { 10291 PetscErrorCode ierr; 10292 10293 PetscFunctionBegin; 10294 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10295 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10296 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10297 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10298 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10299 PetscFunctionReturn(0); 10300 } 10301 10302 /*@C 10303 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries. 10304 10305 Collective on Mat 10306 10307 Input Parameters: 10308 + mat - the matrix 10309 . nblocks - the number of blocks 10310 - bsizes - the size of each block 10311 10312 Output Parameters: 10313 . values - the block inverses in column major order (FORTRAN-like) 10314 10315 Note: 10316 This routine is not available from Fortran. 10317 10318 Level: advanced 10319 10320 .seealso: MatInvertBockDiagonal() 10321 @*/ 10322 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10323 { 10324 PetscErrorCode ierr; 10325 10326 PetscFunctionBegin; 10327 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10328 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10329 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10330 if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10331 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 10332 PetscFunctionReturn(0); 10333 } 10334 10335 /*@ 10336 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10337 10338 Collective on Mat 10339 10340 Input Parameters: 10341 . A - the matrix 10342 10343 Output Parameters: 10344 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10345 10346 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10347 10348 Level: advanced 10349 10350 .seealso: MatInvertBockDiagonal() 10351 @*/ 10352 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10353 { 10354 PetscErrorCode ierr; 10355 const PetscScalar *vals; 10356 PetscInt *dnnz; 10357 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10358 10359 PetscFunctionBegin; 10360 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10361 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10362 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10363 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10364 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10365 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10366 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10367 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10368 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10369 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10370 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10371 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10372 for (i = rstart/bs; i < rend/bs; i++) { 10373 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10374 } 10375 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10376 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10377 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10378 PetscFunctionReturn(0); 10379 } 10380 10381 /*@C 10382 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10383 via MatTransposeColoringCreate(). 10384 10385 Collective on MatTransposeColoring 10386 10387 Input Parameter: 10388 . c - coloring context 10389 10390 Level: intermediate 10391 10392 .seealso: MatTransposeColoringCreate() 10393 @*/ 10394 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10395 { 10396 PetscErrorCode ierr; 10397 MatTransposeColoring matcolor=*c; 10398 10399 PetscFunctionBegin; 10400 if (!matcolor) PetscFunctionReturn(0); 10401 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10402 10403 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10404 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10405 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10406 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10407 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10408 if (matcolor->brows>0) { 10409 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10410 } 10411 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10412 PetscFunctionReturn(0); 10413 } 10414 10415 /*@C 10416 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10417 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10418 MatTransposeColoring to sparse B. 10419 10420 Collective on MatTransposeColoring 10421 10422 Input Parameters: 10423 + B - sparse matrix B 10424 . Btdense - symbolic dense matrix B^T 10425 - coloring - coloring context created with MatTransposeColoringCreate() 10426 10427 Output Parameter: 10428 . Btdense - dense matrix B^T 10429 10430 Level: advanced 10431 10432 Notes: 10433 These are used internally for some implementations of MatRARt() 10434 10435 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10436 10437 @*/ 10438 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10439 { 10440 PetscErrorCode ierr; 10441 10442 PetscFunctionBegin; 10443 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10444 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10445 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10446 10447 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10448 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10449 PetscFunctionReturn(0); 10450 } 10451 10452 /*@C 10453 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10454 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10455 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10456 Csp from Cden. 10457 10458 Collective on MatTransposeColoring 10459 10460 Input Parameters: 10461 + coloring - coloring context created with MatTransposeColoringCreate() 10462 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10463 10464 Output Parameter: 10465 . Csp - sparse matrix 10466 10467 Level: advanced 10468 10469 Notes: 10470 These are used internally for some implementations of MatRARt() 10471 10472 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10473 10474 @*/ 10475 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10476 { 10477 PetscErrorCode ierr; 10478 10479 PetscFunctionBegin; 10480 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10481 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10482 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10483 10484 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10485 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10486 PetscFunctionReturn(0); 10487 } 10488 10489 /*@C 10490 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10491 10492 Collective on Mat 10493 10494 Input Parameters: 10495 + mat - the matrix product C 10496 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10497 10498 Output Parameter: 10499 . color - the new coloring context 10500 10501 Level: intermediate 10502 10503 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10504 MatTransColoringApplyDenToSp() 10505 @*/ 10506 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10507 { 10508 MatTransposeColoring c; 10509 MPI_Comm comm; 10510 PetscErrorCode ierr; 10511 10512 PetscFunctionBegin; 10513 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10514 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10515 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10516 10517 c->ctype = iscoloring->ctype; 10518 if (mat->ops->transposecoloringcreate) { 10519 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10520 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10521 10522 *color = c; 10523 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10524 PetscFunctionReturn(0); 10525 } 10526 10527 /*@ 10528 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10529 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10530 same, otherwise it will be larger 10531 10532 Not Collective 10533 10534 Input Parameter: 10535 . A - the matrix 10536 10537 Output Parameter: 10538 . state - the current state 10539 10540 Notes: 10541 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10542 different matrices 10543 10544 Level: intermediate 10545 10546 @*/ 10547 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10548 { 10549 PetscFunctionBegin; 10550 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10551 *state = mat->nonzerostate; 10552 PetscFunctionReturn(0); 10553 } 10554 10555 /*@ 10556 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10557 matrices from each processor 10558 10559 Collective 10560 10561 Input Parameters: 10562 + comm - the communicators the parallel matrix will live on 10563 . seqmat - the input sequential matrices 10564 . n - number of local columns (or PETSC_DECIDE) 10565 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10566 10567 Output Parameter: 10568 . mpimat - the parallel matrix generated 10569 10570 Level: advanced 10571 10572 Notes: 10573 The number of columns of the matrix in EACH processor MUST be the same. 10574 10575 @*/ 10576 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10577 { 10578 PetscErrorCode ierr; 10579 10580 PetscFunctionBegin; 10581 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10582 if (reuse == MAT_REUSE_MATRIX && seqmat == *mpimat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix"); 10583 10584 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10585 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10586 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10587 PetscFunctionReturn(0); 10588 } 10589 10590 /*@ 10591 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10592 ranks' ownership ranges. 10593 10594 Collective on A 10595 10596 Input Parameters: 10597 + A - the matrix to create subdomains from 10598 - N - requested number of subdomains 10599 10600 10601 Output Parameters: 10602 + n - number of subdomains resulting on this rank 10603 - iss - IS list with indices of subdomains on this rank 10604 10605 Level: advanced 10606 10607 Notes: 10608 number of subdomains must be smaller than the communicator size 10609 @*/ 10610 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10611 { 10612 MPI_Comm comm,subcomm; 10613 PetscMPIInt size,rank,color; 10614 PetscInt rstart,rend,k; 10615 PetscErrorCode ierr; 10616 10617 PetscFunctionBegin; 10618 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10619 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10620 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10621 if (N < 1 || N >= (PetscInt)size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %D, got N = %D",size,N); 10622 *n = 1; 10623 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10624 color = rank/k; 10625 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10626 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10627 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10628 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10629 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10630 PetscFunctionReturn(0); 10631 } 10632 10633 /*@ 10634 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10635 10636 If the interpolation and restriction operators are the same, uses MatPtAP. 10637 If they are not the same, use MatMatMatMult. 10638 10639 Once the coarse grid problem is constructed, correct for interpolation operators 10640 that are not of full rank, which can legitimately happen in the case of non-nested 10641 geometric multigrid. 10642 10643 Input Parameters: 10644 + restrct - restriction operator 10645 . dA - fine grid matrix 10646 . interpolate - interpolation operator 10647 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10648 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10649 10650 Output Parameters: 10651 . A - the Galerkin coarse matrix 10652 10653 Options Database Key: 10654 . -pc_mg_galerkin <both,pmat,mat,none> 10655 10656 Level: developer 10657 10658 .seealso: MatPtAP(), MatMatMatMult() 10659 @*/ 10660 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10661 { 10662 PetscErrorCode ierr; 10663 IS zerorows; 10664 Vec diag; 10665 10666 PetscFunctionBegin; 10667 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10668 /* Construct the coarse grid matrix */ 10669 if (interpolate == restrct) { 10670 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10671 } else { 10672 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10673 } 10674 10675 /* If the interpolation matrix is not of full rank, A will have zero rows. 10676 This can legitimately happen in the case of non-nested geometric multigrid. 10677 In that event, we set the rows of the matrix to the rows of the identity, 10678 ignoring the equations (as the RHS will also be zero). */ 10679 10680 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10681 10682 if (zerorows != NULL) { /* if there are any zero rows */ 10683 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10684 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10685 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10686 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10687 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10688 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10689 } 10690 PetscFunctionReturn(0); 10691 } 10692 10693 /*@C 10694 MatSetOperation - Allows user to set a matrix operation for any matrix type 10695 10696 Logically Collective on Mat 10697 10698 Input Parameters: 10699 + mat - the matrix 10700 . op - the name of the operation 10701 - f - the function that provides the operation 10702 10703 Level: developer 10704 10705 Usage: 10706 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10707 $ ierr = MatCreateXXX(comm,...&A); 10708 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10709 10710 Notes: 10711 See the file include/petscmat.h for a complete list of matrix 10712 operations, which all have the form MATOP_<OPERATION>, where 10713 <OPERATION> is the name (in all capital letters) of the 10714 user interface routine (e.g., MatMult() -> MATOP_MULT). 10715 10716 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10717 sequence as the usual matrix interface routines, since they 10718 are intended to be accessed via the usual matrix interface 10719 routines, e.g., 10720 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10721 10722 In particular each function MUST return an error code of 0 on success and 10723 nonzero on failure. 10724 10725 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10726 10727 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10728 @*/ 10729 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10730 { 10731 PetscFunctionBegin; 10732 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10733 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10734 mat->ops->viewnative = mat->ops->view; 10735 } 10736 (((void(**)(void))mat->ops)[op]) = f; 10737 PetscFunctionReturn(0); 10738 } 10739 10740 /*@C 10741 MatGetOperation - Gets a matrix operation for any matrix type. 10742 10743 Not Collective 10744 10745 Input Parameters: 10746 + mat - the matrix 10747 - op - the name of the operation 10748 10749 Output Parameter: 10750 . f - the function that provides the operation 10751 10752 Level: developer 10753 10754 Usage: 10755 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10756 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10757 10758 Notes: 10759 See the file include/petscmat.h for a complete list of matrix 10760 operations, which all have the form MATOP_<OPERATION>, where 10761 <OPERATION> is the name (in all capital letters) of the 10762 user interface routine (e.g., MatMult() -> MATOP_MULT). 10763 10764 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10765 10766 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 10767 @*/ 10768 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10769 { 10770 PetscFunctionBegin; 10771 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10772 *f = (((void (**)(void))mat->ops)[op]); 10773 PetscFunctionReturn(0); 10774 } 10775 10776 /*@ 10777 MatHasOperation - Determines whether the given matrix supports the particular 10778 operation. 10779 10780 Not Collective 10781 10782 Input Parameters: 10783 + mat - the matrix 10784 - op - the operation, for example, MATOP_GET_DIAGONAL 10785 10786 Output Parameter: 10787 . has - either PETSC_TRUE or PETSC_FALSE 10788 10789 Level: advanced 10790 10791 Notes: 10792 See the file include/petscmat.h for a complete list of matrix 10793 operations, which all have the form MATOP_<OPERATION>, where 10794 <OPERATION> is the name (in all capital letters) of the 10795 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10796 10797 .seealso: MatCreateShell() 10798 @*/ 10799 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10800 { 10801 PetscErrorCode ierr; 10802 10803 PetscFunctionBegin; 10804 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10805 PetscValidType(mat,1); 10806 PetscValidPointer(has,3); 10807 if (mat->ops->hasoperation) { 10808 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 10809 } else { 10810 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10811 else { 10812 *has = PETSC_FALSE; 10813 if (op == MATOP_CREATE_SUBMATRIX) { 10814 PetscMPIInt size; 10815 10816 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10817 if (size == 1) { 10818 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 10819 } 10820 } 10821 } 10822 } 10823 PetscFunctionReturn(0); 10824 } 10825 10826 /*@ 10827 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10828 of the matrix are congruent 10829 10830 Collective on mat 10831 10832 Input Parameters: 10833 . mat - the matrix 10834 10835 Output Parameter: 10836 . cong - either PETSC_TRUE or PETSC_FALSE 10837 10838 Level: beginner 10839 10840 Notes: 10841 10842 .seealso: MatCreate(), MatSetSizes() 10843 @*/ 10844 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 10845 { 10846 PetscErrorCode ierr; 10847 10848 PetscFunctionBegin; 10849 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10850 PetscValidType(mat,1); 10851 PetscValidPointer(cong,2); 10852 if (!mat->rmap || !mat->cmap) { 10853 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10854 PetscFunctionReturn(0); 10855 } 10856 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10857 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 10858 if (*cong) mat->congruentlayouts = 1; 10859 else mat->congruentlayouts = 0; 10860 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10861 PetscFunctionReturn(0); 10862 } 10863 10864 /*@ 10865 MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse, 10866 e.g., matrx product of MatPtAP. 10867 10868 Collective on mat 10869 10870 Input Parameters: 10871 . mat - the matrix 10872 10873 Output Parameter: 10874 . mat - the matrix with intermediate data structures released 10875 10876 Level: advanced 10877 10878 Notes: 10879 10880 .seealso: MatPtAP(), MatMatMult() 10881 @*/ 10882 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat) 10883 { 10884 PetscErrorCode ierr; 10885 10886 PetscFunctionBegin; 10887 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10888 PetscValidType(mat,1); 10889 if (mat->ops->freeintermediatedatastructures) { 10890 ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr); 10891 } 10892 PetscFunctionReturn(0); 10893 } 10894