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