1 /* 2 This is where the abstract matrix operations are defined 3 */ 4 5 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 6 #include <petsc/private/isimpl.h> 7 #include <petsc/private/vecimpl.h> 8 9 /* Logging support */ 10 PetscClassId MAT_CLASSID; 11 PetscClassId MAT_COLORING_CLASSID; 12 PetscClassId MAT_FDCOLORING_CLASSID; 13 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 14 15 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose; 16 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 17 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 18 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 19 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 20 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 21 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 22 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat; 23 PetscLogEvent MAT_TransposeColoringCreate; 24 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 25 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 26 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 27 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 28 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 29 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 30 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols; 31 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 32 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 33 PetscLogEvent MAT_GetMultiProcBlock; 34 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch; 35 PetscLogEvent MAT_ViennaCLCopyToGPU; 36 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU; 37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 38 PetscLogEvent MAT_FactorFactS,MAT_FactorInvS; 39 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 40 41 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0}; 42 43 /*@ 44 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations, 45 for sparse matrices that already have locations it fills the locations with random numbers 46 47 Logically Collective on Mat 48 49 Input Parameters: 50 + x - the matrix 51 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 52 it will create one internally. 53 54 Output Parameter: 55 . x - the matrix 56 57 Example of Usage: 58 .vb 59 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 60 MatSetRandom(x,rctx); 61 PetscRandomDestroy(rctx); 62 .ve 63 64 Level: intermediate 65 66 67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy() 68 @*/ 69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 70 { 71 PetscErrorCode ierr; 72 PetscRandom randObj = NULL; 73 74 PetscFunctionBegin; 75 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 76 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 77 PetscValidType(x,1); 78 79 if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 80 81 if (!rctx) { 82 MPI_Comm comm; 83 ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 84 ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr); 85 ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr); 86 rctx = randObj; 87 } 88 89 ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 90 ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr); 91 ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 92 93 ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 94 ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 95 ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr); 96 PetscFunctionReturn(0); 97 } 98 99 /*@ 100 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 101 102 Logically Collective on Mat 103 104 Input Parameters: 105 . mat - the factored matrix 106 107 Output Parameter: 108 + pivot - the pivot value computed 109 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 110 the share the matrix 111 112 Level: advanced 113 114 Notes: 115 This routine does not work for factorizations done with external packages. 116 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 117 118 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 119 120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 121 @*/ 122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 123 { 124 PetscFunctionBegin; 125 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 126 *pivot = mat->factorerror_zeropivot_value; 127 *row = mat->factorerror_zeropivot_row; 128 PetscFunctionReturn(0); 129 } 130 131 /*@ 132 MatFactorGetError - gets the error code from a factorization 133 134 Logically Collective on Mat 135 136 Input Parameters: 137 . mat - the factored matrix 138 139 Output Parameter: 140 . err - the error code 141 142 Level: advanced 143 144 Notes: 145 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 146 147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 148 @*/ 149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 150 { 151 PetscFunctionBegin; 152 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 153 *err = mat->factorerrortype; 154 PetscFunctionReturn(0); 155 } 156 157 /*@ 158 MatFactorClearError - clears the error code in a factorization 159 160 Logically Collective on Mat 161 162 Input Parameter: 163 . mat - the factored matrix 164 165 Level: developer 166 167 Notes: 168 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 169 170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot() 171 @*/ 172 PetscErrorCode MatFactorClearError(Mat mat) 173 { 174 PetscFunctionBegin; 175 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 176 mat->factorerrortype = MAT_FACTOR_NOERROR; 177 mat->factorerror_zeropivot_value = 0.0; 178 mat->factorerror_zeropivot_row = 0; 179 PetscFunctionReturn(0); 180 } 181 182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 183 { 184 PetscErrorCode ierr; 185 Vec r,l; 186 const PetscScalar *al; 187 PetscInt i,nz,gnz,N,n; 188 189 PetscFunctionBegin; 190 ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr); 191 if (!cols) { /* nonzero rows */ 192 ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 193 ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr); 194 ierr = VecSet(l,0.0);CHKERRQ(ierr); 195 ierr = VecSetRandom(r,NULL);CHKERRQ(ierr); 196 ierr = MatMult(mat,r,l);CHKERRQ(ierr); 197 ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr); 198 } else { /* nonzero columns */ 199 ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr); 200 ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr); 201 ierr = VecSet(r,0.0);CHKERRQ(ierr); 202 ierr = VecSetRandom(l,NULL);CHKERRQ(ierr); 203 ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr); 204 ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr); 205 } 206 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 207 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 208 ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 209 if (gnz != N) { 210 PetscInt *nzr; 211 ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr); 212 if (nz) { 213 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 214 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 215 } 216 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr); 217 } else *nonzero = NULL; 218 if (!cols) { /* nonzero rows */ 219 ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr); 220 } else { 221 ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr); 222 } 223 ierr = VecDestroy(&l);CHKERRQ(ierr); 224 ierr = VecDestroy(&r);CHKERRQ(ierr); 225 PetscFunctionReturn(0); 226 } 227 228 /*@ 229 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 230 231 Input Parameter: 232 . A - the matrix 233 234 Output Parameter: 235 . keptrows - the rows that are not completely zero 236 237 Notes: 238 keptrows is set to NULL if all rows are nonzero. 239 240 Level: intermediate 241 242 @*/ 243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 244 { 245 PetscErrorCode ierr; 246 247 PetscFunctionBegin; 248 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 249 PetscValidType(mat,1); 250 PetscValidPointer(keptrows,2); 251 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 252 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 253 if (!mat->ops->findnonzerorows) { 254 ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr); 255 } else { 256 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr); 257 } 258 PetscFunctionReturn(0); 259 } 260 261 /*@ 262 MatFindZeroRows - Locate all rows that are completely zero in the matrix 263 264 Input Parameter: 265 . A - the matrix 266 267 Output Parameter: 268 . zerorows - the rows that are completely zero 269 270 Notes: 271 zerorows is set to NULL if no rows are zero. 272 273 Level: intermediate 274 275 @*/ 276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 277 { 278 PetscErrorCode ierr; 279 IS keptrows; 280 PetscInt m, n; 281 282 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 283 PetscValidType(mat,1); 284 285 ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr); 286 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 287 In keeping with this convention, we set zerorows to NULL if there are no zero 288 rows. */ 289 if (keptrows == NULL) { 290 *zerorows = NULL; 291 } else { 292 ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr); 293 ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr); 294 ierr = ISDestroy(&keptrows);CHKERRQ(ierr); 295 } 296 PetscFunctionReturn(0); 297 } 298 299 /*@ 300 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 301 302 Not Collective 303 304 Input Parameters: 305 . A - the matrix 306 307 Output Parameters: 308 . a - the diagonal part (which is a SEQUENTIAL matrix) 309 310 Notes: 311 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 312 Use caution, as the reference count on the returned matrix is not incremented and it is used as 313 part of the containing MPI Mat's normal operation. 314 315 Level: advanced 316 317 @*/ 318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 319 { 320 PetscErrorCode ierr; 321 322 PetscFunctionBegin; 323 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 324 PetscValidType(A,1); 325 PetscValidPointer(a,3); 326 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 327 if (!A->ops->getdiagonalblock) { 328 PetscMPIInt size; 329 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 330 if (size == 1) { 331 *a = A; 332 PetscFunctionReturn(0); 333 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type"); 334 } 335 ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr); 336 PetscFunctionReturn(0); 337 } 338 339 /*@ 340 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 341 342 Collective on Mat 343 344 Input Parameters: 345 . mat - the matrix 346 347 Output Parameter: 348 . trace - the sum of the diagonal entries 349 350 Level: advanced 351 352 @*/ 353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 354 { 355 PetscErrorCode ierr; 356 Vec diag; 357 358 PetscFunctionBegin; 359 ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr); 360 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr); 361 ierr = VecSum(diag,trace);CHKERRQ(ierr); 362 ierr = VecDestroy(&diag);CHKERRQ(ierr); 363 PetscFunctionReturn(0); 364 } 365 366 /*@ 367 MatRealPart - Zeros out the imaginary part of the matrix 368 369 Logically Collective on Mat 370 371 Input Parameters: 372 . mat - the matrix 373 374 Level: advanced 375 376 377 .seealso: MatImaginaryPart() 378 @*/ 379 PetscErrorCode MatRealPart(Mat mat) 380 { 381 PetscErrorCode ierr; 382 383 PetscFunctionBegin; 384 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 385 PetscValidType(mat,1); 386 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 387 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 388 if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 389 MatCheckPreallocated(mat,1); 390 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr); 391 PetscFunctionReturn(0); 392 } 393 394 /*@C 395 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 396 397 Collective on Mat 398 399 Input Parameter: 400 . mat - the matrix 401 402 Output Parameters: 403 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 404 - ghosts - the global indices of the ghost points 405 406 Notes: 407 the nghosts and ghosts are suitable to pass into VecCreateGhost() 408 409 Level: advanced 410 411 @*/ 412 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 413 { 414 PetscErrorCode ierr; 415 416 PetscFunctionBegin; 417 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 418 PetscValidType(mat,1); 419 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 420 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 421 if (!mat->ops->getghosts) { 422 if (nghosts) *nghosts = 0; 423 if (ghosts) *ghosts = 0; 424 } else { 425 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr); 426 } 427 PetscFunctionReturn(0); 428 } 429 430 431 /*@ 432 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 433 434 Logically Collective on Mat 435 436 Input Parameters: 437 . mat - the matrix 438 439 Level: advanced 440 441 442 .seealso: MatRealPart() 443 @*/ 444 PetscErrorCode MatImaginaryPart(Mat mat) 445 { 446 PetscErrorCode ierr; 447 448 PetscFunctionBegin; 449 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 450 PetscValidType(mat,1); 451 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 452 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 453 if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 454 MatCheckPreallocated(mat,1); 455 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr); 456 PetscFunctionReturn(0); 457 } 458 459 /*@ 460 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 461 462 Not Collective 463 464 Input Parameter: 465 . mat - the matrix 466 467 Output Parameters: 468 + missing - is any diagonal missing 469 - dd - first diagonal entry that is missing (optional) on this process 470 471 Level: advanced 472 473 474 .seealso: MatRealPart() 475 @*/ 476 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 477 { 478 PetscErrorCode ierr; 479 480 PetscFunctionBegin; 481 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 482 PetscValidType(mat,1); 483 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 484 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 485 if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 486 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr); 487 PetscFunctionReturn(0); 488 } 489 490 /*@C 491 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 492 for each row that you get to ensure that your application does 493 not bleed memory. 494 495 Not Collective 496 497 Input Parameters: 498 + mat - the matrix 499 - row - the row to get 500 501 Output Parameters: 502 + ncols - if not NULL, the number of nonzeros in the row 503 . cols - if not NULL, the column numbers 504 - vals - if not NULL, the values 505 506 Notes: 507 This routine is provided for people who need to have direct access 508 to the structure of a matrix. We hope that we provide enough 509 high-level matrix routines that few users will need it. 510 511 MatGetRow() always returns 0-based column indices, regardless of 512 whether the internal representation is 0-based (default) or 1-based. 513 514 For better efficiency, set cols and/or vals to NULL if you do 515 not wish to extract these quantities. 516 517 The user can only examine the values extracted with MatGetRow(); 518 the values cannot be altered. To change the matrix entries, one 519 must use MatSetValues(). 520 521 You can only have one call to MatGetRow() outstanding for a particular 522 matrix at a time, per processor. MatGetRow() can only obtain rows 523 associated with the given processor, it cannot get rows from the 524 other processors; for that we suggest using MatCreateSubMatrices(), then 525 MatGetRow() on the submatrix. The row index passed to MatGetRow() 526 is in the global number of rows. 527 528 Fortran Notes: 529 The calling sequence from Fortran is 530 .vb 531 MatGetRow(matrix,row,ncols,cols,values,ierr) 532 Mat matrix (input) 533 integer row (input) 534 integer ncols (output) 535 integer cols(maxcols) (output) 536 double precision (or double complex) values(maxcols) output 537 .ve 538 where maxcols >= maximum nonzeros in any row of the matrix. 539 540 541 Caution: 542 Do not try to change the contents of the output arrays (cols and vals). 543 In some cases, this may corrupt the matrix. 544 545 Level: advanced 546 547 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal() 548 @*/ 549 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 550 { 551 PetscErrorCode ierr; 552 PetscInt incols; 553 554 PetscFunctionBegin; 555 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 556 PetscValidType(mat,1); 557 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 558 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 559 if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 560 MatCheckPreallocated(mat,1); 561 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 562 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr); 563 if (ncols) *ncols = incols; 564 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 565 PetscFunctionReturn(0); 566 } 567 568 /*@ 569 MatConjugate - replaces the matrix values with their complex conjugates 570 571 Logically Collective on Mat 572 573 Input Parameters: 574 . mat - the matrix 575 576 Level: advanced 577 578 .seealso: VecConjugate() 579 @*/ 580 PetscErrorCode MatConjugate(Mat mat) 581 { 582 #if defined(PETSC_USE_COMPLEX) 583 PetscErrorCode ierr; 584 585 PetscFunctionBegin; 586 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 587 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 588 if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov"); 589 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr); 590 #else 591 PetscFunctionBegin; 592 #endif 593 PetscFunctionReturn(0); 594 } 595 596 /*@C 597 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 598 599 Not Collective 600 601 Input Parameters: 602 + mat - the matrix 603 . row - the row to get 604 . ncols, cols - the number of nonzeros and their columns 605 - vals - if nonzero the column values 606 607 Notes: 608 This routine should be called after you have finished examining the entries. 609 610 This routine zeros out ncols, cols, and vals. This is to prevent accidental 611 us of the array after it has been restored. If you pass NULL, it will 612 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 613 614 Fortran Notes: 615 The calling sequence from Fortran is 616 .vb 617 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 618 Mat matrix (input) 619 integer row (input) 620 integer ncols (output) 621 integer cols(maxcols) (output) 622 double precision (or double complex) values(maxcols) output 623 .ve 624 Where maxcols >= maximum nonzeros in any row of the matrix. 625 626 In Fortran MatRestoreRow() MUST be called after MatGetRow() 627 before another call to MatGetRow() can be made. 628 629 Level: advanced 630 631 .seealso: MatGetRow() 632 @*/ 633 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 634 { 635 PetscErrorCode ierr; 636 637 PetscFunctionBegin; 638 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 639 if (ncols) PetscValidIntPointer(ncols,3); 640 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 641 if (!mat->ops->restorerow) PetscFunctionReturn(0); 642 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 643 if (ncols) *ncols = 0; 644 if (cols) *cols = NULL; 645 if (vals) *vals = NULL; 646 PetscFunctionReturn(0); 647 } 648 649 /*@ 650 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 651 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 652 653 Not Collective 654 655 Input Parameters: 656 . mat - the matrix 657 658 Notes: 659 The flag is to ensure that users are aware of MatGetRow() only provides the upper triangular part of the row for the matrices in MATSBAIJ format. 660 661 Level: advanced 662 663 .seealso: MatRestoreRowUpperTriangular() 664 @*/ 665 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 666 { 667 PetscErrorCode ierr; 668 669 PetscFunctionBegin; 670 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 671 PetscValidType(mat,1); 672 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 673 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 674 MatCheckPreallocated(mat,1); 675 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 676 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr); 677 PetscFunctionReturn(0); 678 } 679 680 /*@ 681 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 682 683 Not Collective 684 685 Input Parameters: 686 . mat - the matrix 687 688 Notes: 689 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 690 691 692 Level: advanced 693 694 .seealso: MatGetRowUpperTriangular() 695 @*/ 696 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 697 { 698 PetscErrorCode ierr; 699 700 PetscFunctionBegin; 701 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 702 PetscValidType(mat,1); 703 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 704 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 705 MatCheckPreallocated(mat,1); 706 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 707 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr); 708 PetscFunctionReturn(0); 709 } 710 711 /*@C 712 MatSetOptionsPrefix - Sets the prefix used for searching for all 713 Mat options in the database. 714 715 Logically Collective on Mat 716 717 Input Parameter: 718 + A - the Mat context 719 - prefix - the prefix to prepend to all option names 720 721 Notes: 722 A hyphen (-) must NOT be given at the beginning of the prefix name. 723 The first character of all runtime options is AUTOMATICALLY the hyphen. 724 725 Level: advanced 726 727 .seealso: MatSetFromOptions() 728 @*/ 729 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 730 { 731 PetscErrorCode ierr; 732 733 PetscFunctionBegin; 734 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 735 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 736 PetscFunctionReturn(0); 737 } 738 739 /*@C 740 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 741 Mat options in the database. 742 743 Logically Collective on Mat 744 745 Input Parameters: 746 + A - the Mat context 747 - prefix - the prefix to prepend to all option names 748 749 Notes: 750 A hyphen (-) must NOT be given at the beginning of the prefix name. 751 The first character of all runtime options is AUTOMATICALLY the hyphen. 752 753 Level: advanced 754 755 .seealso: MatGetOptionsPrefix() 756 @*/ 757 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 758 { 759 PetscErrorCode ierr; 760 761 PetscFunctionBegin; 762 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 763 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 764 PetscFunctionReturn(0); 765 } 766 767 /*@C 768 MatGetOptionsPrefix - Sets the prefix used for searching for all 769 Mat options in the database. 770 771 Not Collective 772 773 Input Parameter: 774 . A - the Mat context 775 776 Output Parameter: 777 . prefix - pointer to the prefix string used 778 779 Notes: 780 On the fortran side, the user should pass in a string 'prefix' of 781 sufficient length to hold the prefix. 782 783 Level: advanced 784 785 .seealso: MatAppendOptionsPrefix() 786 @*/ 787 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 788 { 789 PetscErrorCode ierr; 790 791 PetscFunctionBegin; 792 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 793 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 794 PetscFunctionReturn(0); 795 } 796 797 /*@ 798 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 799 800 Collective on Mat 801 802 Input Parameters: 803 . A - the Mat context 804 805 Notes: 806 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 807 Currently support MPIAIJ and SEQAIJ. 808 809 Level: beginner 810 811 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation() 812 @*/ 813 PetscErrorCode MatResetPreallocation(Mat A) 814 { 815 PetscErrorCode ierr; 816 817 PetscFunctionBegin; 818 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 819 PetscValidType(A,1); 820 ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr); 821 PetscFunctionReturn(0); 822 } 823 824 825 /*@ 826 MatSetUp - Sets up the internal matrix data structures for the later use. 827 828 Collective on Mat 829 830 Input Parameters: 831 . A - the Mat context 832 833 Notes: 834 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 835 836 If a suitable preallocation routine is used, this function does not need to be called. 837 838 See the Performance chapter of the PETSc users manual for how to preallocate matrices 839 840 Level: beginner 841 842 .seealso: MatCreate(), MatDestroy() 843 @*/ 844 PetscErrorCode MatSetUp(Mat A) 845 { 846 PetscMPIInt size; 847 PetscErrorCode ierr; 848 849 PetscFunctionBegin; 850 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 851 if (!((PetscObject)A)->type_name) { 852 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr); 853 if (size == 1) { 854 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr); 855 } else { 856 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr); 857 } 858 } 859 if (!A->preallocated && A->ops->setup) { 860 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 861 ierr = (*A->ops->setup)(A);CHKERRQ(ierr); 862 } 863 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 864 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 865 A->preallocated = PETSC_TRUE; 866 PetscFunctionReturn(0); 867 } 868 869 #if defined(PETSC_HAVE_SAWS) 870 #include <petscviewersaws.h> 871 #endif 872 873 /*@C 874 MatViewFromOptions - View from Options 875 876 Collective on Mat 877 878 Input Parameters: 879 + A - the Mat context 880 . obj - Optional object 881 - name - command line option 882 883 Level: intermediate 884 .seealso: Mat, MatView, PetscObjectViewFromOptions(), MatCreate() 885 @*/ 886 PetscErrorCode MatViewFromOptions(Mat A,PetscObject obj,const char name[]) 887 { 888 PetscErrorCode ierr; 889 890 PetscFunctionBegin; 891 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 892 ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr); 893 PetscFunctionReturn(0); 894 } 895 896 /*@C 897 MatView - Visualizes a matrix object. 898 899 Collective on Mat 900 901 Input Parameters: 902 + mat - the matrix 903 - viewer - visualization context 904 905 Notes: 906 The available visualization contexts include 907 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 908 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 909 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 910 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 911 912 The user can open alternative visualization contexts with 913 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 914 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 915 specified file; corresponding input uses MatLoad() 916 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 917 an X window display 918 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 919 Currently only the sequential dense and AIJ 920 matrix types support the Socket viewer. 921 922 The user can call PetscViewerPushFormat() to specify the output 923 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 924 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 925 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 926 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 927 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 928 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 929 format common among all matrix types 930 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 931 format (which is in many cases the same as the default) 932 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 933 size and structure (not the matrix entries) 934 - PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 935 the matrix structure 936 937 Options Database Keys: 938 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 939 . -mat_view ::ascii_info_detail - Prints more detailed info 940 . -mat_view - Prints matrix in ASCII format 941 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 942 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 943 . -display <name> - Sets display name (default is host) 944 . -draw_pause <sec> - Sets number of seconds to pause after display 945 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 946 . -viewer_socket_machine <machine> - 947 . -viewer_socket_port <port> - 948 . -mat_view binary - save matrix to file in binary format 949 - -viewer_binary_filename <name> - 950 Level: beginner 951 952 Notes: 953 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 954 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 955 956 See the manual page for MatLoad() for the exact format of the binary file when the binary 957 viewer is used. 958 959 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 960 viewer is used. 961 962 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 963 and then use the following mouse functions. 964 + left mouse: zoom in 965 . middle mouse: zoom out 966 - right mouse: continue with the simulation 967 968 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 969 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 970 @*/ 971 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 972 { 973 PetscErrorCode ierr; 974 PetscInt rows,cols,rbs,cbs; 975 PetscBool iascii,ibinary,isstring; 976 PetscViewerFormat format; 977 PetscMPIInt size; 978 #if defined(PETSC_HAVE_SAWS) 979 PetscBool issaws; 980 #endif 981 982 PetscFunctionBegin; 983 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 984 PetscValidType(mat,1); 985 if (!viewer) { 986 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr); 987 } 988 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 989 PetscCheckSameComm(mat,1,viewer,2); 990 MatCheckPreallocated(mat,1); 991 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 992 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 993 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 994 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 995 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 996 if (ibinary) { 997 PetscBool mpiio; 998 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr); 999 if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag"); 1000 } 1001 1002 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1003 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1004 if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1005 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed"); 1006 } 1007 1008 #if defined(PETSC_HAVE_SAWS) 1009 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 1010 #endif 1011 if (iascii) { 1012 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1013 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr); 1014 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1015 MatNullSpace nullsp,transnullsp; 1016 1017 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1018 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1019 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 1020 if (rbs != 1 || cbs != 1) { 1021 if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs=%D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);} 1022 else {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);} 1023 } else { 1024 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr); 1025 } 1026 if (mat->factortype) { 1027 MatSolverType solver; 1028 ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr); 1029 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr); 1030 } 1031 if (mat->ops->getinfo) { 1032 MatInfo info; 1033 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 1034 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr); 1035 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr); 1036 } 1037 ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr); 1038 ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr); 1039 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);} 1040 if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached transposed null space\n");CHKERRQ(ierr);} 1041 ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr); 1042 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached near null space\n");CHKERRQ(ierr);} 1043 } 1044 #if defined(PETSC_HAVE_SAWS) 1045 } else if (issaws) { 1046 PetscMPIInt rank; 1047 1048 ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr); 1049 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1050 if (!((PetscObject)mat)->amsmem && !rank) { 1051 ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr); 1052 } 1053 #endif 1054 } else if (isstring) { 1055 const char *type; 1056 ierr = MatGetType(mat,&type);CHKERRQ(ierr); 1057 ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr); 1058 if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);} 1059 } 1060 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1061 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1062 ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr); 1063 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1064 } else if (mat->ops->view) { 1065 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1066 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 1067 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1068 } 1069 if (iascii) { 1070 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1071 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1072 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1073 } 1074 } 1075 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1076 PetscFunctionReturn(0); 1077 } 1078 1079 #if defined(PETSC_USE_DEBUG) 1080 #include <../src/sys/totalview/tv_data_display.h> 1081 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1082 { 1083 TV_add_row("Local rows", "int", &mat->rmap->n); 1084 TV_add_row("Local columns", "int", &mat->cmap->n); 1085 TV_add_row("Global rows", "int", &mat->rmap->N); 1086 TV_add_row("Global columns", "int", &mat->cmap->N); 1087 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1088 return TV_format_OK; 1089 } 1090 #endif 1091 1092 /*@C 1093 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1094 with MatView(). The matrix format is determined from the options database. 1095 Generates a parallel MPI matrix if the communicator has more than one 1096 processor. The default matrix type is AIJ. 1097 1098 Collective on PetscViewer 1099 1100 Input Parameters: 1101 + newmat - the newly loaded matrix, this needs to have been created with MatCreate() 1102 or some related function before a call to MatLoad() 1103 - viewer - binary/HDF5 file viewer 1104 1105 Options Database Keys: 1106 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1107 block size 1108 . -matload_block_size <bs> 1109 1110 Level: beginner 1111 1112 Notes: 1113 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1114 Mat before calling this routine if you wish to set it from the options database. 1115 1116 MatLoad() automatically loads into the options database any options 1117 given in the file filename.info where filename is the name of the file 1118 that was passed to the PetscViewerBinaryOpen(). The options in the info 1119 file will be ignored if you use the -viewer_binary_skip_info option. 1120 1121 If the type or size of newmat is not set before a call to MatLoad, PETSc 1122 sets the default matrix type AIJ and sets the local and global sizes. 1123 If type and/or size is already set, then the same are used. 1124 1125 In parallel, each processor can load a subset of rows (or the 1126 entire matrix). This routine is especially useful when a large 1127 matrix is stored on disk and only part of it is desired on each 1128 processor. For example, a parallel solver may access only some of 1129 the rows from each processor. The algorithm used here reads 1130 relatively small blocks of data rather than reading the entire 1131 matrix and then subsetting it. 1132 1133 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5. 1134 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(), 1135 or the sequence like 1136 $ PetscViewer v; 1137 $ PetscViewerCreate(PETSC_COMM_WORLD,&v); 1138 $ PetscViewerSetType(v,PETSCVIEWERBINARY); 1139 $ PetscViewerSetFromOptions(v); 1140 $ PetscViewerFileSetMode(v,FILE_MODE_READ); 1141 $ PetscViewerFileSetName(v,"datafile"); 1142 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option 1143 $ -viewer_type {binary,hdf5} 1144 1145 See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach, 1146 and src/mat/examples/tutorials/ex10.c with the second approach. 1147 1148 Notes about the PETSc binary format: 1149 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks 1150 is read onto rank 0 and then shipped to its destination rank, one after another. 1151 Multiple objects, both matrices and vectors, can be stored within the same file. 1152 Their PetscObject name is ignored; they are loaded in the order of their storage. 1153 1154 Most users should not need to know the details of the binary storage 1155 format, since MatLoad() and MatView() completely hide these details. 1156 But for anyone who's interested, the standard binary matrix storage 1157 format is 1158 1159 $ PetscInt MAT_FILE_CLASSID 1160 $ PetscInt number of rows 1161 $ PetscInt number of columns 1162 $ PetscInt total number of nonzeros 1163 $ PetscInt *number nonzeros in each row 1164 $ PetscInt *column indices of all nonzeros (starting index is zero) 1165 $ PetscScalar *values of all nonzeros 1166 1167 PETSc automatically does the byte swapping for 1168 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1169 linux, Windows and the paragon; thus if you write your own binary 1170 read/write routines you have to swap the bytes; see PetscBinaryRead() 1171 and PetscBinaryWrite() to see how this may be done. 1172 1173 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1174 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used. 1175 Each processor's chunk is loaded independently by its owning rank. 1176 Multiple objects, both matrices and vectors, can be stored within the same file. 1177 They are looked up by their PetscObject name. 1178 1179 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1180 by default the same structure and naming of the AIJ arrays and column count 1181 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1182 $ save example.mat A b -v7.3 1183 can be directly read by this routine (see Reference 1 for details). 1184 Note that depending on your MATLAB version, this format might be a default, 1185 otherwise you can set it as default in Preferences. 1186 1187 Unless -nocompression flag is used to save the file in MATLAB, 1188 PETSc must be configured with ZLIB package. 1189 1190 See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c 1191 1192 Current HDF5 (MAT-File) limitations: 1193 This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices. 1194 1195 Corresponding MatView() is not yet implemented. 1196 1197 The loaded matrix is actually a transpose of the original one in MATLAB, 1198 unless you push PETSC_VIEWER_HDF5_MAT format (see examples above). 1199 With this format, matrix is automatically transposed by PETSc, 1200 unless the matrix is marked as SPD or symmetric 1201 (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC). 1202 1203 References: 1204 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1205 1206 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad() 1207 1208 @*/ 1209 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer) 1210 { 1211 PetscErrorCode ierr; 1212 PetscBool flg; 1213 1214 PetscFunctionBegin; 1215 PetscValidHeaderSpecific(newmat,MAT_CLASSID,1); 1216 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1217 1218 if (!((PetscObject)newmat)->type_name) { 1219 ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 1220 } 1221 1222 flg = PETSC_FALSE; 1223 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr); 1224 if (flg) { 1225 ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 1226 ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); 1227 } 1228 flg = PETSC_FALSE; 1229 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr); 1230 if (flg) { 1231 ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 1232 } 1233 1234 if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type"); 1235 ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1236 ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr); 1237 ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1238 PetscFunctionReturn(0); 1239 } 1240 1241 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1242 { 1243 PetscErrorCode ierr; 1244 Mat_Redundant *redund = *redundant; 1245 PetscInt i; 1246 1247 PetscFunctionBegin; 1248 if (redund){ 1249 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1250 ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr); 1251 ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr); 1252 ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr); 1253 } else { 1254 ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr); 1255 ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr); 1256 ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr); 1257 for (i=0; i<redund->nrecvs; i++) { 1258 ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr); 1259 ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr); 1260 } 1261 ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr); 1262 } 1263 1264 if (redund->subcomm) { 1265 ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr); 1266 } 1267 ierr = PetscFree(redund);CHKERRQ(ierr); 1268 } 1269 PetscFunctionReturn(0); 1270 } 1271 1272 /*@ 1273 MatDestroy - Frees space taken by a matrix. 1274 1275 Collective on Mat 1276 1277 Input Parameter: 1278 . A - the matrix 1279 1280 Level: beginner 1281 1282 @*/ 1283 PetscErrorCode MatDestroy(Mat *A) 1284 { 1285 PetscErrorCode ierr; 1286 1287 PetscFunctionBegin; 1288 if (!*A) PetscFunctionReturn(0); 1289 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1290 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1291 1292 /* if memory was published with SAWs then destroy it */ 1293 ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr); 1294 if ((*A)->ops->destroy) { 1295 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr); 1296 } 1297 1298 ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr); 1299 ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr); 1300 ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr); 1301 ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr); 1302 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr); 1303 ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr); 1304 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr); 1305 ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr); 1306 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr); 1307 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr); 1308 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr); 1309 PetscFunctionReturn(0); 1310 } 1311 1312 /*@C 1313 MatSetValues - Inserts or adds a block of values into a matrix. 1314 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1315 MUST be called after all calls to MatSetValues() have been completed. 1316 1317 Not Collective 1318 1319 Input Parameters: 1320 + mat - the matrix 1321 . v - a logically two-dimensional array of values 1322 . m, idxm - the number of rows and their global indices 1323 . n, idxn - the number of columns and their global indices 1324 - addv - either ADD_VALUES or INSERT_VALUES, where 1325 ADD_VALUES adds values to any existing entries, and 1326 INSERT_VALUES replaces existing entries with new values 1327 1328 Notes: 1329 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1330 MatSetUp() before using this routine 1331 1332 By default the values, v, are row-oriented. See MatSetOption() for other options. 1333 1334 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1335 options cannot be mixed without intervening calls to the assembly 1336 routines. 1337 1338 MatSetValues() uses 0-based row and column numbers in Fortran 1339 as well as in C. 1340 1341 Negative indices may be passed in idxm and idxn, these rows and columns are 1342 simply ignored. This allows easily inserting element stiffness matrices 1343 with homogeneous Dirchlet boundary conditions that you don't want represented 1344 in the matrix. 1345 1346 Efficiency Alert: 1347 The routine MatSetValuesBlocked() may offer much better efficiency 1348 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1349 1350 Level: beginner 1351 1352 Developer Notes: 1353 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1354 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1355 1356 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1357 InsertMode, INSERT_VALUES, ADD_VALUES 1358 @*/ 1359 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1360 { 1361 PetscErrorCode ierr; 1362 #if defined(PETSC_USE_DEBUG) 1363 PetscInt i,j; 1364 #endif 1365 1366 PetscFunctionBeginHot; 1367 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1368 PetscValidType(mat,1); 1369 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1370 PetscValidIntPointer(idxm,3); 1371 PetscValidIntPointer(idxn,5); 1372 MatCheckPreallocated(mat,1); 1373 1374 if (mat->insertmode == NOT_SET_VALUES) { 1375 mat->insertmode = addv; 1376 } 1377 #if defined(PETSC_USE_DEBUG) 1378 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1379 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1380 if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1381 1382 for (i=0; i<m; i++) { 1383 for (j=0; j<n; j++) { 1384 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1385 #if defined(PETSC_USE_COMPLEX) 1386 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]); 1387 #else 1388 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]); 1389 #endif 1390 } 1391 } 1392 #endif 1393 1394 if (mat->assembled) { 1395 mat->was_assembled = PETSC_TRUE; 1396 mat->assembled = PETSC_FALSE; 1397 } 1398 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1399 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1400 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1401 PetscFunctionReturn(0); 1402 } 1403 1404 1405 /*@ 1406 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1407 values into a matrix 1408 1409 Not Collective 1410 1411 Input Parameters: 1412 + mat - the matrix 1413 . row - the (block) row to set 1414 - v - a logically two-dimensional array of values 1415 1416 Notes: 1417 By the values, v, are column-oriented (for the block version) and sorted 1418 1419 All the nonzeros in the row must be provided 1420 1421 The matrix must have previously had its column indices set 1422 1423 The row must belong to this process 1424 1425 Level: intermediate 1426 1427 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1428 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1429 @*/ 1430 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1431 { 1432 PetscErrorCode ierr; 1433 PetscInt globalrow; 1434 1435 PetscFunctionBegin; 1436 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1437 PetscValidType(mat,1); 1438 PetscValidScalarPointer(v,2); 1439 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr); 1440 ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr); 1441 PetscFunctionReturn(0); 1442 } 1443 1444 /*@ 1445 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1446 values into a matrix 1447 1448 Not Collective 1449 1450 Input Parameters: 1451 + mat - the matrix 1452 . row - the (block) row to set 1453 - 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 1454 1455 Notes: 1456 The values, v, are column-oriented for the block version. 1457 1458 All the nonzeros in the row must be provided 1459 1460 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1461 1462 The row must belong to this process 1463 1464 Level: advanced 1465 1466 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1467 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1468 @*/ 1469 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1470 { 1471 PetscErrorCode ierr; 1472 1473 PetscFunctionBeginHot; 1474 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1475 PetscValidType(mat,1); 1476 MatCheckPreallocated(mat,1); 1477 PetscValidScalarPointer(v,2); 1478 #if defined(PETSC_USE_DEBUG) 1479 if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1480 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1481 #endif 1482 mat->insertmode = INSERT_VALUES; 1483 1484 if (mat->assembled) { 1485 mat->was_assembled = PETSC_TRUE; 1486 mat->assembled = PETSC_FALSE; 1487 } 1488 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1489 if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1490 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr); 1491 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1492 PetscFunctionReturn(0); 1493 } 1494 1495 /*@ 1496 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1497 Using structured grid indexing 1498 1499 Not Collective 1500 1501 Input Parameters: 1502 + mat - the matrix 1503 . m - number of rows being entered 1504 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1505 . n - number of columns being entered 1506 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1507 . v - a logically two-dimensional array of values 1508 - addv - either ADD_VALUES or INSERT_VALUES, where 1509 ADD_VALUES adds values to any existing entries, and 1510 INSERT_VALUES replaces existing entries with new values 1511 1512 Notes: 1513 By default the values, v, are row-oriented. See MatSetOption() for other options. 1514 1515 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1516 options cannot be mixed without intervening calls to the assembly 1517 routines. 1518 1519 The grid coordinates are across the entire grid, not just the local portion 1520 1521 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1522 as well as in C. 1523 1524 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1525 1526 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1527 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1528 1529 The columns and rows in the stencil passed in MUST be contained within the 1530 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1531 if you create a DMDA with an overlap of one grid level and on a particular process its first 1532 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1533 first i index you can use in your column and row indices in MatSetStencil() is 5. 1534 1535 In Fortran idxm and idxn should be declared as 1536 $ MatStencil idxm(4,m),idxn(4,n) 1537 and the values inserted using 1538 $ idxm(MatStencil_i,1) = i 1539 $ idxm(MatStencil_j,1) = j 1540 $ idxm(MatStencil_k,1) = k 1541 $ idxm(MatStencil_c,1) = c 1542 etc 1543 1544 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1545 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1546 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1547 DM_BOUNDARY_PERIODIC boundary type. 1548 1549 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 1550 a single value per point) you can skip filling those indices. 1551 1552 Inspired by the structured grid interface to the HYPRE package 1553 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1554 1555 Efficiency Alert: 1556 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1557 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1558 1559 Level: beginner 1560 1561 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1562 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1563 @*/ 1564 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1565 { 1566 PetscErrorCode ierr; 1567 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1568 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1569 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1570 1571 PetscFunctionBegin; 1572 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1573 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1574 PetscValidType(mat,1); 1575 PetscValidIntPointer(idxm,3); 1576 PetscValidIntPointer(idxn,5); 1577 1578 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1579 jdxm = buf; jdxn = buf+m; 1580 } else { 1581 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1582 jdxm = bufm; jdxn = bufn; 1583 } 1584 for (i=0; i<m; i++) { 1585 for (j=0; j<3-sdim; j++) dxm++; 1586 tmp = *dxm++ - starts[0]; 1587 for (j=0; j<dim-1; j++) { 1588 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1589 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1590 } 1591 if (mat->stencil.noc) dxm++; 1592 jdxm[i] = tmp; 1593 } 1594 for (i=0; i<n; i++) { 1595 for (j=0; j<3-sdim; j++) dxn++; 1596 tmp = *dxn++ - starts[0]; 1597 for (j=0; j<dim-1; j++) { 1598 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1599 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1600 } 1601 if (mat->stencil.noc) dxn++; 1602 jdxn[i] = tmp; 1603 } 1604 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1605 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1606 PetscFunctionReturn(0); 1607 } 1608 1609 /*@ 1610 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1611 Using structured grid indexing 1612 1613 Not Collective 1614 1615 Input Parameters: 1616 + mat - the matrix 1617 . m - number of rows being entered 1618 . idxm - grid coordinates for matrix rows being entered 1619 . n - number of columns being entered 1620 . idxn - grid coordinates for matrix columns being entered 1621 . v - a logically two-dimensional array of values 1622 - addv - either ADD_VALUES or INSERT_VALUES, where 1623 ADD_VALUES adds values to any existing entries, and 1624 INSERT_VALUES replaces existing entries with new values 1625 1626 Notes: 1627 By default the values, v, are row-oriented and unsorted. 1628 See MatSetOption() for other options. 1629 1630 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1631 options cannot be mixed without intervening calls to the assembly 1632 routines. 1633 1634 The grid coordinates are across the entire grid, not just the local portion 1635 1636 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1637 as well as in C. 1638 1639 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1640 1641 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1642 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1643 1644 The columns and rows in the stencil passed in MUST be contained within the 1645 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1646 if you create a DMDA with an overlap of one grid level and on a particular process its first 1647 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1648 first i index you can use in your column and row indices in MatSetStencil() is 5. 1649 1650 In Fortran idxm and idxn should be declared as 1651 $ MatStencil idxm(4,m),idxn(4,n) 1652 and the values inserted using 1653 $ idxm(MatStencil_i,1) = i 1654 $ idxm(MatStencil_j,1) = j 1655 $ idxm(MatStencil_k,1) = k 1656 etc 1657 1658 Negative indices may be passed in idxm and idxn, these rows and columns are 1659 simply ignored. This allows easily inserting element stiffness matrices 1660 with homogeneous Dirchlet boundary conditions that you don't want represented 1661 in the matrix. 1662 1663 Inspired by the structured grid interface to the HYPRE package 1664 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1665 1666 Level: beginner 1667 1668 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1669 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1670 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1671 @*/ 1672 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1673 { 1674 PetscErrorCode ierr; 1675 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1676 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1677 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1678 1679 PetscFunctionBegin; 1680 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1681 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1682 PetscValidType(mat,1); 1683 PetscValidIntPointer(idxm,3); 1684 PetscValidIntPointer(idxn,5); 1685 PetscValidScalarPointer(v,6); 1686 1687 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1688 jdxm = buf; jdxn = buf+m; 1689 } else { 1690 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1691 jdxm = bufm; jdxn = bufn; 1692 } 1693 for (i=0; i<m; i++) { 1694 for (j=0; j<3-sdim; j++) dxm++; 1695 tmp = *dxm++ - starts[0]; 1696 for (j=0; j<sdim-1; j++) { 1697 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1698 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1699 } 1700 dxm++; 1701 jdxm[i] = tmp; 1702 } 1703 for (i=0; i<n; i++) { 1704 for (j=0; j<3-sdim; j++) dxn++; 1705 tmp = *dxn++ - starts[0]; 1706 for (j=0; j<sdim-1; j++) { 1707 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1708 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1709 } 1710 dxn++; 1711 jdxn[i] = tmp; 1712 } 1713 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1714 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1715 PetscFunctionReturn(0); 1716 } 1717 1718 /*@ 1719 MatSetStencil - Sets the grid information for setting values into a matrix via 1720 MatSetValuesStencil() 1721 1722 Not Collective 1723 1724 Input Parameters: 1725 + mat - the matrix 1726 . dim - dimension of the grid 1, 2, or 3 1727 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1728 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1729 - dof - number of degrees of freedom per node 1730 1731 1732 Inspired by the structured grid interface to the HYPRE package 1733 (www.llnl.gov/CASC/hyper) 1734 1735 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1736 user. 1737 1738 Level: beginner 1739 1740 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1741 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1742 @*/ 1743 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1744 { 1745 PetscInt i; 1746 1747 PetscFunctionBegin; 1748 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1749 PetscValidIntPointer(dims,3); 1750 PetscValidIntPointer(starts,4); 1751 1752 mat->stencil.dim = dim + (dof > 1); 1753 for (i=0; i<dim; i++) { 1754 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1755 mat->stencil.starts[i] = starts[dim-i-1]; 1756 } 1757 mat->stencil.dims[dim] = dof; 1758 mat->stencil.starts[dim] = 0; 1759 mat->stencil.noc = (PetscBool)(dof == 1); 1760 PetscFunctionReturn(0); 1761 } 1762 1763 /*@C 1764 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1765 1766 Not Collective 1767 1768 Input Parameters: 1769 + mat - the matrix 1770 . v - a logically two-dimensional array of values 1771 . m, idxm - the number of block rows and their global block indices 1772 . n, idxn - the number of block columns and their global block indices 1773 - addv - either ADD_VALUES or INSERT_VALUES, where 1774 ADD_VALUES adds values to any existing entries, and 1775 INSERT_VALUES replaces existing entries with new values 1776 1777 Notes: 1778 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1779 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1780 1781 The m and n count the NUMBER of blocks in the row direction and column direction, 1782 NOT the total number of rows/columns; for example, if the block size is 2 and 1783 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1784 The values in idxm would be 1 2; that is the first index for each block divided by 1785 the block size. 1786 1787 Note that you must call MatSetBlockSize() when constructing this matrix (before 1788 preallocating it). 1789 1790 By default the values, v, are row-oriented, so the layout of 1791 v is the same as for MatSetValues(). See MatSetOption() for other options. 1792 1793 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1794 options cannot be mixed without intervening calls to the assembly 1795 routines. 1796 1797 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1798 as well as in C. 1799 1800 Negative indices may be passed in idxm and idxn, these rows and columns are 1801 simply ignored. This allows easily inserting element stiffness matrices 1802 with homogeneous Dirchlet boundary conditions that you don't want represented 1803 in the matrix. 1804 1805 Each time an entry is set within a sparse matrix via MatSetValues(), 1806 internal searching must be done to determine where to place the 1807 data in the matrix storage space. By instead inserting blocks of 1808 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1809 reduced. 1810 1811 Example: 1812 $ Suppose m=n=2 and block size(bs) = 2 The array is 1813 $ 1814 $ 1 2 | 3 4 1815 $ 5 6 | 7 8 1816 $ - - - | - - - 1817 $ 9 10 | 11 12 1818 $ 13 14 | 15 16 1819 $ 1820 $ v[] should be passed in like 1821 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1822 $ 1823 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1824 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1825 1826 Level: intermediate 1827 1828 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1829 @*/ 1830 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1831 { 1832 PetscErrorCode ierr; 1833 1834 PetscFunctionBeginHot; 1835 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1836 PetscValidType(mat,1); 1837 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1838 PetscValidIntPointer(idxm,3); 1839 PetscValidIntPointer(idxn,5); 1840 PetscValidScalarPointer(v,6); 1841 MatCheckPreallocated(mat,1); 1842 if (mat->insertmode == NOT_SET_VALUES) { 1843 mat->insertmode = addv; 1844 } 1845 #if defined(PETSC_USE_DEBUG) 1846 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1847 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1848 if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1849 #endif 1850 1851 if (mat->assembled) { 1852 mat->was_assembled = PETSC_TRUE; 1853 mat->assembled = PETSC_FALSE; 1854 } 1855 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1856 if (mat->ops->setvaluesblocked) { 1857 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1858 } else { 1859 PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn; 1860 PetscInt i,j,bs,cbs; 1861 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr); 1862 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1863 iidxm = buf; iidxn = buf + m*bs; 1864 } else { 1865 ierr = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr); 1866 iidxm = bufr; iidxn = bufc; 1867 } 1868 for (i=0; i<m; i++) { 1869 for (j=0; j<bs; j++) { 1870 iidxm[i*bs+j] = bs*idxm[i] + j; 1871 } 1872 } 1873 for (i=0; i<n; i++) { 1874 for (j=0; j<cbs; j++) { 1875 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1876 } 1877 } 1878 ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr); 1879 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1880 } 1881 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1882 PetscFunctionReturn(0); 1883 } 1884 1885 /*@ 1886 MatGetValues - Gets a block of values from a matrix. 1887 1888 Not Collective; currently only returns a local block 1889 1890 Input Parameters: 1891 + mat - the matrix 1892 . v - a logically two-dimensional array for storing the values 1893 . m, idxm - the number of rows and their global indices 1894 - n, idxn - the number of columns and their global indices 1895 1896 Notes: 1897 The user must allocate space (m*n PetscScalars) for the values, v. 1898 The values, v, are then returned in a row-oriented format, 1899 analogous to that used by default in MatSetValues(). 1900 1901 MatGetValues() uses 0-based row and column numbers in 1902 Fortran as well as in C. 1903 1904 MatGetValues() requires that the matrix has been assembled 1905 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1906 MatSetValues() and MatGetValues() CANNOT be made in succession 1907 without intermediate matrix assembly. 1908 1909 Negative row or column indices will be ignored and those locations in v[] will be 1910 left unchanged. 1911 1912 Level: advanced 1913 1914 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues() 1915 @*/ 1916 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1917 { 1918 PetscErrorCode ierr; 1919 1920 PetscFunctionBegin; 1921 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1922 PetscValidType(mat,1); 1923 if (!m || !n) PetscFunctionReturn(0); 1924 PetscValidIntPointer(idxm,3); 1925 PetscValidIntPointer(idxn,5); 1926 PetscValidScalarPointer(v,6); 1927 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1928 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1929 if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1930 MatCheckPreallocated(mat,1); 1931 1932 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1933 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 1934 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1935 PetscFunctionReturn(0); 1936 } 1937 1938 /*@ 1939 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 1940 the same size. Currently, this can only be called once and creates the given matrix. 1941 1942 Not Collective 1943 1944 Input Parameters: 1945 + mat - the matrix 1946 . nb - the number of blocks 1947 . bs - the number of rows (and columns) in each block 1948 . rows - a concatenation of the rows for each block 1949 - v - a concatenation of logically two-dimensional arrays of values 1950 1951 Notes: 1952 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 1953 1954 Level: advanced 1955 1956 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1957 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1958 @*/ 1959 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 1960 { 1961 PetscErrorCode ierr; 1962 1963 PetscFunctionBegin; 1964 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1965 PetscValidType(mat,1); 1966 PetscValidScalarPointer(rows,4); 1967 PetscValidScalarPointer(v,5); 1968 #if defined(PETSC_USE_DEBUG) 1969 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1970 #endif 1971 1972 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1973 if (mat->ops->setvaluesbatch) { 1974 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr); 1975 } else { 1976 PetscInt b; 1977 for (b = 0; b < nb; ++b) { 1978 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr); 1979 } 1980 } 1981 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1982 PetscFunctionReturn(0); 1983 } 1984 1985 /*@ 1986 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 1987 the routine MatSetValuesLocal() to allow users to insert matrix entries 1988 using a local (per-processor) numbering. 1989 1990 Not Collective 1991 1992 Input Parameters: 1993 + x - the matrix 1994 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 1995 - cmapping - column mapping 1996 1997 Level: intermediate 1998 1999 2000 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal() 2001 @*/ 2002 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2003 { 2004 PetscErrorCode ierr; 2005 2006 PetscFunctionBegin; 2007 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2008 PetscValidType(x,1); 2009 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2010 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2011 2012 if (x->ops->setlocaltoglobalmapping) { 2013 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr); 2014 } else { 2015 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr); 2016 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr); 2017 } 2018 PetscFunctionReturn(0); 2019 } 2020 2021 2022 /*@ 2023 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2024 2025 Not Collective 2026 2027 Input Parameters: 2028 . A - the matrix 2029 2030 Output Parameters: 2031 + rmapping - row mapping 2032 - cmapping - column mapping 2033 2034 Level: advanced 2035 2036 2037 .seealso: MatSetValuesLocal() 2038 @*/ 2039 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2040 { 2041 PetscFunctionBegin; 2042 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2043 PetscValidType(A,1); 2044 if (rmapping) PetscValidPointer(rmapping,2); 2045 if (cmapping) PetscValidPointer(cmapping,3); 2046 if (rmapping) *rmapping = A->rmap->mapping; 2047 if (cmapping) *cmapping = A->cmap->mapping; 2048 PetscFunctionReturn(0); 2049 } 2050 2051 /*@ 2052 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2053 2054 Not Collective 2055 2056 Input Parameters: 2057 . A - the matrix 2058 2059 Output Parameters: 2060 + rmap - row layout 2061 - cmap - column layout 2062 2063 Level: advanced 2064 2065 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping() 2066 @*/ 2067 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2068 { 2069 PetscFunctionBegin; 2070 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2071 PetscValidType(A,1); 2072 if (rmap) PetscValidPointer(rmap,2); 2073 if (cmap) PetscValidPointer(cmap,3); 2074 if (rmap) *rmap = A->rmap; 2075 if (cmap) *cmap = A->cmap; 2076 PetscFunctionReturn(0); 2077 } 2078 2079 /*@C 2080 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2081 using a local ordering of the nodes. 2082 2083 Not Collective 2084 2085 Input Parameters: 2086 + mat - the matrix 2087 . nrow, irow - number of rows and their local indices 2088 . ncol, icol - number of columns and their local indices 2089 . y - a logically two-dimensional array of values 2090 - addv - either INSERT_VALUES or ADD_VALUES, where 2091 ADD_VALUES adds values to any existing entries, and 2092 INSERT_VALUES replaces existing entries with new values 2093 2094 Notes: 2095 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2096 MatSetUp() before using this routine 2097 2098 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2099 2100 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2101 options cannot be mixed without intervening calls to the assembly 2102 routines. 2103 2104 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2105 MUST be called after all calls to MatSetValuesLocal() have been completed. 2106 2107 Level: intermediate 2108 2109 Developer Notes: 2110 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2111 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2112 2113 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 2114 MatSetValueLocal() 2115 @*/ 2116 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2117 { 2118 PetscErrorCode ierr; 2119 2120 PetscFunctionBeginHot; 2121 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2122 PetscValidType(mat,1); 2123 MatCheckPreallocated(mat,1); 2124 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2125 PetscValidIntPointer(irow,3); 2126 PetscValidIntPointer(icol,5); 2127 if (mat->insertmode == NOT_SET_VALUES) { 2128 mat->insertmode = addv; 2129 } 2130 #if defined(PETSC_USE_DEBUG) 2131 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2132 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2133 if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2134 #endif 2135 2136 if (mat->assembled) { 2137 mat->was_assembled = PETSC_TRUE; 2138 mat->assembled = PETSC_FALSE; 2139 } 2140 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2141 if (mat->ops->setvalueslocal) { 2142 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2143 } else { 2144 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2145 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2146 irowm = buf; icolm = buf+nrow; 2147 } else { 2148 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2149 irowm = bufr; icolm = bufc; 2150 } 2151 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2152 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2153 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2154 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2155 } 2156 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2157 PetscFunctionReturn(0); 2158 } 2159 2160 /*@C 2161 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2162 using a local ordering of the nodes a block at a time. 2163 2164 Not Collective 2165 2166 Input Parameters: 2167 + x - the matrix 2168 . nrow, irow - number of rows and their local indices 2169 . ncol, icol - number of columns and their local indices 2170 . y - a logically two-dimensional array of values 2171 - addv - either INSERT_VALUES or ADD_VALUES, where 2172 ADD_VALUES adds values to any existing entries, and 2173 INSERT_VALUES replaces existing entries with new values 2174 2175 Notes: 2176 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2177 MatSetUp() before using this routine 2178 2179 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2180 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2181 2182 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2183 options cannot be mixed without intervening calls to the assembly 2184 routines. 2185 2186 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2187 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2188 2189 Level: intermediate 2190 2191 Developer Notes: 2192 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2193 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2194 2195 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(), 2196 MatSetValuesLocal(), MatSetValuesBlocked() 2197 @*/ 2198 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2199 { 2200 PetscErrorCode ierr; 2201 2202 PetscFunctionBeginHot; 2203 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2204 PetscValidType(mat,1); 2205 MatCheckPreallocated(mat,1); 2206 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2207 PetscValidIntPointer(irow,3); 2208 PetscValidIntPointer(icol,5); 2209 PetscValidScalarPointer(y,6); 2210 if (mat->insertmode == NOT_SET_VALUES) { 2211 mat->insertmode = addv; 2212 } 2213 #if defined(PETSC_USE_DEBUG) 2214 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2215 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2216 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); 2217 #endif 2218 2219 if (mat->assembled) { 2220 mat->was_assembled = PETSC_TRUE; 2221 mat->assembled = PETSC_FALSE; 2222 } 2223 #if defined(PETSC_USE_DEBUG) 2224 /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2225 if (mat->rmap->mapping) { 2226 PetscInt irbs, rbs; 2227 ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr); 2228 ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr); 2229 if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs); 2230 } 2231 if (mat->cmap->mapping) { 2232 PetscInt icbs, cbs; 2233 ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr); 2234 ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr); 2235 if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs); 2236 } 2237 #endif 2238 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2239 if (mat->ops->setvaluesblockedlocal) { 2240 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2241 } else { 2242 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2243 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2244 irowm = buf; icolm = buf + nrow; 2245 } else { 2246 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2247 irowm = bufr; icolm = bufc; 2248 } 2249 ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2250 ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2251 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2252 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2253 } 2254 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2255 PetscFunctionReturn(0); 2256 } 2257 2258 /*@ 2259 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2260 2261 Collective on Mat 2262 2263 Input Parameters: 2264 + mat - the matrix 2265 - x - the vector to be multiplied 2266 2267 Output Parameters: 2268 . y - the result 2269 2270 Notes: 2271 The vectors x and y cannot be the same. I.e., one cannot 2272 call MatMult(A,y,y). 2273 2274 Level: developer 2275 2276 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2277 @*/ 2278 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2279 { 2280 PetscErrorCode ierr; 2281 2282 PetscFunctionBegin; 2283 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2284 PetscValidType(mat,1); 2285 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2286 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2287 2288 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2289 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2290 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2291 MatCheckPreallocated(mat,1); 2292 2293 if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2294 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr); 2295 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2296 PetscFunctionReturn(0); 2297 } 2298 2299 /* --------------------------------------------------------*/ 2300 /*@ 2301 MatMult - Computes the matrix-vector product, y = Ax. 2302 2303 Neighbor-wise Collective on Mat 2304 2305 Input Parameters: 2306 + mat - the matrix 2307 - x - the vector to be multiplied 2308 2309 Output Parameters: 2310 . y - the result 2311 2312 Notes: 2313 The vectors x and y cannot be the same. I.e., one cannot 2314 call MatMult(A,y,y). 2315 2316 Level: beginner 2317 2318 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2319 @*/ 2320 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2321 { 2322 PetscErrorCode ierr; 2323 2324 PetscFunctionBegin; 2325 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2326 PetscValidType(mat,1); 2327 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2328 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2329 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2330 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2331 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2332 #if !defined(PETSC_HAVE_CONSTRAINTS) 2333 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); 2334 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); 2335 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); 2336 #endif 2337 ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr); 2338 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2339 MatCheckPreallocated(mat,1); 2340 2341 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2342 if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2343 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2344 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2345 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2346 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2347 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2348 PetscFunctionReturn(0); 2349 } 2350 2351 /*@ 2352 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2353 2354 Neighbor-wise Collective on Mat 2355 2356 Input Parameters: 2357 + mat - the matrix 2358 - x - the vector to be multiplied 2359 2360 Output Parameters: 2361 . y - the result 2362 2363 Notes: 2364 The vectors x and y cannot be the same. I.e., one cannot 2365 call MatMultTranspose(A,y,y). 2366 2367 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2368 use MatMultHermitianTranspose() 2369 2370 Level: beginner 2371 2372 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2373 @*/ 2374 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2375 { 2376 PetscErrorCode ierr; 2377 2378 PetscFunctionBegin; 2379 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2380 PetscValidType(mat,1); 2381 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2382 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2383 2384 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2385 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2386 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2387 #if !defined(PETSC_HAVE_CONSTRAINTS) 2388 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); 2389 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); 2390 #endif 2391 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2392 MatCheckPreallocated(mat,1); 2393 2394 if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined"); 2395 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2396 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2397 ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr); 2398 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2399 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2400 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2401 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2402 PetscFunctionReturn(0); 2403 } 2404 2405 /*@ 2406 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2407 2408 Neighbor-wise Collective on Mat 2409 2410 Input Parameters: 2411 + mat - the matrix 2412 - x - the vector to be multilplied 2413 2414 Output Parameters: 2415 . y - the result 2416 2417 Notes: 2418 The vectors x and y cannot be the same. I.e., one cannot 2419 call MatMultHermitianTranspose(A,y,y). 2420 2421 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2422 2423 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2424 2425 Level: beginner 2426 2427 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2428 @*/ 2429 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2430 { 2431 PetscErrorCode ierr; 2432 Vec w; 2433 2434 PetscFunctionBegin; 2435 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2436 PetscValidType(mat,1); 2437 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2438 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2439 2440 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2441 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2442 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2443 #if !defined(PETSC_HAVE_CONSTRAINTS) 2444 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); 2445 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); 2446 #endif 2447 MatCheckPreallocated(mat,1); 2448 2449 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2450 if (mat->ops->multhermitiantranspose) { 2451 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2452 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr); 2453 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2454 } else { 2455 ierr = VecDuplicate(x,&w);CHKERRQ(ierr); 2456 ierr = VecCopy(x,w);CHKERRQ(ierr); 2457 ierr = VecConjugate(w);CHKERRQ(ierr); 2458 ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr); 2459 ierr = VecDestroy(&w);CHKERRQ(ierr); 2460 ierr = VecConjugate(y);CHKERRQ(ierr); 2461 } 2462 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2463 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2464 PetscFunctionReturn(0); 2465 } 2466 2467 /*@ 2468 MatMultAdd - Computes v3 = v2 + A * v1. 2469 2470 Neighbor-wise Collective on Mat 2471 2472 Input Parameters: 2473 + mat - the matrix 2474 - v1, v2 - the vectors 2475 2476 Output Parameters: 2477 . v3 - the result 2478 2479 Notes: 2480 The vectors v1 and v3 cannot be the same. I.e., one cannot 2481 call MatMultAdd(A,v1,v2,v1). 2482 2483 Level: beginner 2484 2485 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2486 @*/ 2487 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2488 { 2489 PetscErrorCode ierr; 2490 2491 PetscFunctionBegin; 2492 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2493 PetscValidType(mat,1); 2494 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2495 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2496 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2497 2498 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2499 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2500 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); 2501 /* 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); 2502 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); */ 2503 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); 2504 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); 2505 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2506 MatCheckPreallocated(mat,1); 2507 2508 if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name); 2509 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2510 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2511 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2512 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2513 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2514 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2515 PetscFunctionReturn(0); 2516 } 2517 2518 /*@ 2519 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2520 2521 Neighbor-wise Collective on Mat 2522 2523 Input Parameters: 2524 + mat - the matrix 2525 - v1, v2 - the vectors 2526 2527 Output Parameters: 2528 . v3 - the result 2529 2530 Notes: 2531 The vectors v1 and v3 cannot be the same. I.e., one cannot 2532 call MatMultTransposeAdd(A,v1,v2,v1). 2533 2534 Level: beginner 2535 2536 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2537 @*/ 2538 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2539 { 2540 PetscErrorCode ierr; 2541 2542 PetscFunctionBegin; 2543 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2544 PetscValidType(mat,1); 2545 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2546 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2547 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2548 2549 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2550 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2551 if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2552 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2553 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); 2554 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); 2555 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); 2556 MatCheckPreallocated(mat,1); 2557 2558 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2559 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2560 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2561 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2562 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2563 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2564 PetscFunctionReturn(0); 2565 } 2566 2567 /*@ 2568 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2569 2570 Neighbor-wise Collective on Mat 2571 2572 Input Parameters: 2573 + mat - the matrix 2574 - v1, v2 - the vectors 2575 2576 Output Parameters: 2577 . v3 - the result 2578 2579 Notes: 2580 The vectors v1 and v3 cannot be the same. I.e., one cannot 2581 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2582 2583 Level: beginner 2584 2585 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2586 @*/ 2587 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2588 { 2589 PetscErrorCode ierr; 2590 2591 PetscFunctionBegin; 2592 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2593 PetscValidType(mat,1); 2594 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2595 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2596 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2597 2598 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2599 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2600 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2601 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); 2602 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); 2603 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); 2604 MatCheckPreallocated(mat,1); 2605 2606 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2607 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2608 if (mat->ops->multhermitiantransposeadd) { 2609 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2610 } else { 2611 Vec w,z; 2612 ierr = VecDuplicate(v1,&w);CHKERRQ(ierr); 2613 ierr = VecCopy(v1,w);CHKERRQ(ierr); 2614 ierr = VecConjugate(w);CHKERRQ(ierr); 2615 ierr = VecDuplicate(v3,&z);CHKERRQ(ierr); 2616 ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr); 2617 ierr = VecDestroy(&w);CHKERRQ(ierr); 2618 ierr = VecConjugate(z);CHKERRQ(ierr); 2619 if (v2 != v3) { 2620 ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr); 2621 } else { 2622 ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr); 2623 } 2624 ierr = VecDestroy(&z);CHKERRQ(ierr); 2625 } 2626 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2627 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2628 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2629 PetscFunctionReturn(0); 2630 } 2631 2632 /*@ 2633 MatMultConstrained - The inner multiplication routine for a 2634 constrained matrix P^T A P. 2635 2636 Neighbor-wise Collective on Mat 2637 2638 Input Parameters: 2639 + mat - the matrix 2640 - x - the vector to be multilplied 2641 2642 Output Parameters: 2643 . y - the result 2644 2645 Notes: 2646 The vectors x and y cannot be the same. I.e., one cannot 2647 call MatMult(A,y,y). 2648 2649 Level: beginner 2650 2651 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2652 @*/ 2653 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y) 2654 { 2655 PetscErrorCode ierr; 2656 2657 PetscFunctionBegin; 2658 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2659 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2660 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2661 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2662 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2663 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2664 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); 2665 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); 2666 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); 2667 2668 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2669 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2670 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr); 2671 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2672 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2673 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2674 PetscFunctionReturn(0); 2675 } 2676 2677 /*@ 2678 MatMultTransposeConstrained - The inner multiplication routine for a 2679 constrained matrix P^T A^T P. 2680 2681 Neighbor-wise Collective on Mat 2682 2683 Input Parameters: 2684 + mat - the matrix 2685 - x - the vector to be multilplied 2686 2687 Output Parameters: 2688 . y - the result 2689 2690 Notes: 2691 The vectors x and y cannot be the same. I.e., one cannot 2692 call MatMult(A,y,y). 2693 2694 Level: beginner 2695 2696 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2697 @*/ 2698 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 2699 { 2700 PetscErrorCode ierr; 2701 2702 PetscFunctionBegin; 2703 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2704 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2705 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2706 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2707 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2708 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2709 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); 2710 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); 2711 2712 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2713 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 2714 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2715 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2716 PetscFunctionReturn(0); 2717 } 2718 2719 /*@C 2720 MatGetFactorType - gets the type of factorization it is 2721 2722 Not Collective 2723 2724 Input Parameters: 2725 . mat - the matrix 2726 2727 Output Parameters: 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(), MatSetFactorType() 2733 @*/ 2734 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2735 { 2736 PetscFunctionBegin; 2737 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2738 PetscValidType(mat,1); 2739 PetscValidPointer(t,2); 2740 *t = mat->factortype; 2741 PetscFunctionReturn(0); 2742 } 2743 2744 /*@C 2745 MatSetFactorType - sets the type of factorization it is 2746 2747 Logically Collective on Mat 2748 2749 Input Parameters: 2750 + mat - the matrix 2751 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2752 2753 Level: intermediate 2754 2755 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType() 2756 @*/ 2757 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2758 { 2759 PetscFunctionBegin; 2760 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2761 PetscValidType(mat,1); 2762 mat->factortype = t; 2763 PetscFunctionReturn(0); 2764 } 2765 2766 /* ------------------------------------------------------------*/ 2767 /*@C 2768 MatGetInfo - Returns information about matrix storage (number of 2769 nonzeros, memory, etc.). 2770 2771 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2772 2773 Input Parameters: 2774 . mat - the matrix 2775 2776 Output Parameters: 2777 + flag - flag indicating the type of parameters to be returned 2778 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2779 MAT_GLOBAL_SUM - sum over all processors) 2780 - info - matrix information context 2781 2782 Notes: 2783 The MatInfo context contains a variety of matrix data, including 2784 number of nonzeros allocated and used, number of mallocs during 2785 matrix assembly, etc. Additional information for factored matrices 2786 is provided (such as the fill ratio, number of mallocs during 2787 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2788 when using the runtime options 2789 $ -info -mat_view ::ascii_info 2790 2791 Example for C/C++ Users: 2792 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2793 data within the MatInfo context. For example, 2794 .vb 2795 MatInfo info; 2796 Mat A; 2797 double mal, nz_a, nz_u; 2798 2799 MatGetInfo(A,MAT_LOCAL,&info); 2800 mal = info.mallocs; 2801 nz_a = info.nz_allocated; 2802 .ve 2803 2804 Example for Fortran Users: 2805 Fortran users should declare info as a double precision 2806 array of dimension MAT_INFO_SIZE, and then extract the parameters 2807 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2808 a complete list of parameter names. 2809 .vb 2810 double precision info(MAT_INFO_SIZE) 2811 double precision mal, nz_a 2812 Mat A 2813 integer ierr 2814 2815 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2816 mal = info(MAT_INFO_MALLOCS) 2817 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2818 .ve 2819 2820 Level: intermediate 2821 2822 Developer Note: fortran interface is not autogenerated as the f90 2823 interface defintion cannot be generated correctly [due to MatInfo] 2824 2825 .seealso: MatStashGetInfo() 2826 2827 @*/ 2828 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2829 { 2830 PetscErrorCode ierr; 2831 2832 PetscFunctionBegin; 2833 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2834 PetscValidType(mat,1); 2835 PetscValidPointer(info,3); 2836 if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2837 MatCheckPreallocated(mat,1); 2838 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 2839 PetscFunctionReturn(0); 2840 } 2841 2842 /* 2843 This is used by external packages where it is not easy to get the info from the actual 2844 matrix factorization. 2845 */ 2846 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2847 { 2848 PetscErrorCode ierr; 2849 2850 PetscFunctionBegin; 2851 ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr); 2852 PetscFunctionReturn(0); 2853 } 2854 2855 /* ----------------------------------------------------------*/ 2856 2857 /*@C 2858 MatLUFactor - Performs in-place LU factorization of matrix. 2859 2860 Collective on Mat 2861 2862 Input Parameters: 2863 + mat - the matrix 2864 . row - row permutation 2865 . col - column permutation 2866 - info - options for factorization, includes 2867 $ fill - expected fill as ratio of original fill. 2868 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2869 $ Run with the option -info to determine an optimal value to use 2870 2871 Notes: 2872 Most users should employ the simplified KSP interface for linear solvers 2873 instead of working directly with matrix algebra routines such as this. 2874 See, e.g., KSPCreate(). 2875 2876 This changes the state of the matrix to a factored matrix; it cannot be used 2877 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2878 2879 Level: developer 2880 2881 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 2882 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 2883 2884 Developer Note: fortran interface is not autogenerated as the f90 2885 interface defintion cannot be generated correctly [due to MatFactorInfo] 2886 2887 @*/ 2888 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2889 { 2890 PetscErrorCode ierr; 2891 MatFactorInfo tinfo; 2892 2893 PetscFunctionBegin; 2894 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2895 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2896 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2897 if (info) PetscValidPointer(info,4); 2898 PetscValidType(mat,1); 2899 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2900 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2901 if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2902 MatCheckPreallocated(mat,1); 2903 if (!info) { 2904 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2905 info = &tinfo; 2906 } 2907 2908 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2909 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 2910 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2911 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2912 PetscFunctionReturn(0); 2913 } 2914 2915 /*@C 2916 MatILUFactor - Performs in-place ILU factorization of matrix. 2917 2918 Collective on Mat 2919 2920 Input Parameters: 2921 + mat - the matrix 2922 . row - row permutation 2923 . col - column permutation 2924 - info - structure containing 2925 $ levels - number of levels of fill. 2926 $ expected fill - as ratio of original fill. 2927 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2928 missing diagonal entries) 2929 2930 Notes: 2931 Probably really in-place only when level of fill is zero, otherwise allocates 2932 new space to store factored matrix and deletes previous memory. 2933 2934 Most users should employ the simplified KSP interface for linear solvers 2935 instead of working directly with matrix algebra routines such as this. 2936 See, e.g., KSPCreate(). 2937 2938 Level: developer 2939 2940 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 2941 2942 Developer Note: fortran interface is not autogenerated as the f90 2943 interface defintion cannot be generated correctly [due to MatFactorInfo] 2944 2945 @*/ 2946 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2947 { 2948 PetscErrorCode ierr; 2949 2950 PetscFunctionBegin; 2951 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2952 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2953 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2954 PetscValidPointer(info,4); 2955 PetscValidType(mat,1); 2956 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 2957 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2958 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2959 if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2960 MatCheckPreallocated(mat,1); 2961 2962 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2963 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 2964 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2965 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2966 PetscFunctionReturn(0); 2967 } 2968 2969 /*@C 2970 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 2971 Call this routine before calling MatLUFactorNumeric(). 2972 2973 Collective on Mat 2974 2975 Input Parameters: 2976 + fact - the factor matrix obtained with MatGetFactor() 2977 . mat - the matrix 2978 . row, col - row and column permutations 2979 - info - options for factorization, includes 2980 $ fill - expected fill as ratio of original fill. 2981 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2982 $ Run with the option -info to determine an optimal value to use 2983 2984 2985 Notes: 2986 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 2987 2988 Most users should employ the simplified KSP interface for linear solvers 2989 instead of working directly with matrix algebra routines such as this. 2990 See, e.g., KSPCreate(). 2991 2992 Level: developer 2993 2994 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize() 2995 2996 Developer Note: fortran interface is not autogenerated as the f90 2997 interface defintion cannot be generated correctly [due to MatFactorInfo] 2998 2999 @*/ 3000 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3001 { 3002 PetscErrorCode ierr; 3003 MatFactorInfo tinfo; 3004 3005 PetscFunctionBegin; 3006 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3007 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3008 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3009 if (info) PetscValidPointer(info,4); 3010 PetscValidType(mat,1); 3011 PetscValidPointer(fact,5); 3012 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3013 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3014 if (!(fact)->ops->lufactorsymbolic) { 3015 MatSolverType spackage; 3016 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3017 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage); 3018 } 3019 MatCheckPreallocated(mat,2); 3020 if (!info) { 3021 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3022 info = &tinfo; 3023 } 3024 3025 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3026 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 3027 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3028 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3029 PetscFunctionReturn(0); 3030 } 3031 3032 /*@C 3033 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3034 Call this routine after first calling MatLUFactorSymbolic(). 3035 3036 Collective on Mat 3037 3038 Input Parameters: 3039 + fact - the factor matrix obtained with MatGetFactor() 3040 . mat - the matrix 3041 - info - options for factorization 3042 3043 Notes: 3044 See MatLUFactor() for in-place factorization. See 3045 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3046 3047 Most users should employ the simplified KSP interface for linear solvers 3048 instead of working directly with matrix algebra routines such as this. 3049 See, e.g., KSPCreate(). 3050 3051 Level: developer 3052 3053 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 3054 3055 Developer Note: fortran interface is not autogenerated as the f90 3056 interface defintion cannot be generated correctly [due to MatFactorInfo] 3057 3058 @*/ 3059 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3060 { 3061 MatFactorInfo tinfo; 3062 PetscErrorCode ierr; 3063 3064 PetscFunctionBegin; 3065 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3066 PetscValidType(mat,1); 3067 PetscValidPointer(fact,2); 3068 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3069 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3070 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); 3071 3072 if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3073 MatCheckPreallocated(mat,2); 3074 if (!info) { 3075 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3076 info = &tinfo; 3077 } 3078 3079 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3080 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr); 3081 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3082 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3083 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3084 PetscFunctionReturn(0); 3085 } 3086 3087 /*@C 3088 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3089 symmetric matrix. 3090 3091 Collective on Mat 3092 3093 Input Parameters: 3094 + mat - the matrix 3095 . perm - row and column permutations 3096 - f - expected fill as ratio of original fill 3097 3098 Notes: 3099 See MatLUFactor() for the nonsymmetric case. See also 3100 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3101 3102 Most users should employ the simplified KSP interface for linear solvers 3103 instead of working directly with matrix algebra routines such as this. 3104 See, e.g., KSPCreate(). 3105 3106 Level: developer 3107 3108 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 3109 MatGetOrdering() 3110 3111 Developer Note: fortran interface is not autogenerated as the f90 3112 interface defintion cannot be generated correctly [due to MatFactorInfo] 3113 3114 @*/ 3115 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3116 { 3117 PetscErrorCode ierr; 3118 MatFactorInfo tinfo; 3119 3120 PetscFunctionBegin; 3121 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3122 PetscValidType(mat,1); 3123 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3124 if (info) PetscValidPointer(info,3); 3125 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3126 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3127 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3128 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); 3129 MatCheckPreallocated(mat,1); 3130 if (!info) { 3131 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3132 info = &tinfo; 3133 } 3134 3135 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3136 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr); 3137 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3138 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3139 PetscFunctionReturn(0); 3140 } 3141 3142 /*@C 3143 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3144 of a symmetric matrix. 3145 3146 Collective on Mat 3147 3148 Input Parameters: 3149 + fact - the factor matrix obtained with MatGetFactor() 3150 . mat - the matrix 3151 . perm - row and column permutations 3152 - info - options for factorization, includes 3153 $ fill - expected fill as ratio of original fill. 3154 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3155 $ Run with the option -info to determine an optimal value to use 3156 3157 Notes: 3158 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3159 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3160 3161 Most users should employ the simplified KSP interface for linear solvers 3162 instead of working directly with matrix algebra routines such as this. 3163 See, e.g., KSPCreate(). 3164 3165 Level: developer 3166 3167 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 3168 MatGetOrdering() 3169 3170 Developer Note: fortran interface is not autogenerated as the f90 3171 interface defintion cannot be generated correctly [due to MatFactorInfo] 3172 3173 @*/ 3174 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3175 { 3176 PetscErrorCode ierr; 3177 MatFactorInfo tinfo; 3178 3179 PetscFunctionBegin; 3180 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3181 PetscValidType(mat,1); 3182 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3183 if (info) PetscValidPointer(info,3); 3184 PetscValidPointer(fact,4); 3185 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3186 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3187 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3188 if (!(fact)->ops->choleskyfactorsymbolic) { 3189 MatSolverType spackage; 3190 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3191 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage); 3192 } 3193 MatCheckPreallocated(mat,2); 3194 if (!info) { 3195 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3196 info = &tinfo; 3197 } 3198 3199 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3200 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 3201 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3202 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3203 PetscFunctionReturn(0); 3204 } 3205 3206 /*@C 3207 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3208 of a symmetric matrix. Call this routine after first calling 3209 MatCholeskyFactorSymbolic(). 3210 3211 Collective on Mat 3212 3213 Input Parameters: 3214 + fact - the factor matrix obtained with MatGetFactor() 3215 . mat - the initial matrix 3216 . info - options for factorization 3217 - fact - the symbolic factor of mat 3218 3219 3220 Notes: 3221 Most users should employ the simplified KSP interface for linear solvers 3222 instead of working directly with matrix algebra routines such as this. 3223 See, e.g., KSPCreate(). 3224 3225 Level: developer 3226 3227 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 3228 3229 Developer Note: fortran interface is not autogenerated as the f90 3230 interface defintion cannot be generated correctly [due to MatFactorInfo] 3231 3232 @*/ 3233 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3234 { 3235 MatFactorInfo tinfo; 3236 PetscErrorCode ierr; 3237 3238 PetscFunctionBegin; 3239 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3240 PetscValidType(mat,1); 3241 PetscValidPointer(fact,2); 3242 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3243 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3244 if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3245 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); 3246 MatCheckPreallocated(mat,2); 3247 if (!info) { 3248 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3249 info = &tinfo; 3250 } 3251 3252 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3253 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr); 3254 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3255 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3256 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3257 PetscFunctionReturn(0); 3258 } 3259 3260 /* ----------------------------------------------------------------*/ 3261 /*@ 3262 MatSolve - Solves A x = b, given a factored matrix. 3263 3264 Neighbor-wise Collective on Mat 3265 3266 Input Parameters: 3267 + mat - the factored matrix 3268 - b - the right-hand-side vector 3269 3270 Output Parameter: 3271 . x - the result vector 3272 3273 Notes: 3274 The vectors b and x cannot be the same. I.e., one cannot 3275 call MatSolve(A,x,x). 3276 3277 Notes: 3278 Most users should employ the simplified KSP interface for linear solvers 3279 instead of working directly with matrix algebra routines such as this. 3280 See, e.g., KSPCreate(). 3281 3282 Level: developer 3283 3284 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3285 @*/ 3286 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3287 { 3288 PetscErrorCode ierr; 3289 3290 PetscFunctionBegin; 3291 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3292 PetscValidType(mat,1); 3293 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3294 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3295 PetscCheckSameComm(mat,1,b,2); 3296 PetscCheckSameComm(mat,1,x,3); 3297 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3298 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); 3299 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); 3300 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); 3301 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3302 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3303 MatCheckPreallocated(mat,1); 3304 3305 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3306 if (mat->factorerrortype) { 3307 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3308 ierr = VecSetInf(x);CHKERRQ(ierr); 3309 } else { 3310 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3311 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 3312 } 3313 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3314 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3315 PetscFunctionReturn(0); 3316 } 3317 3318 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans) 3319 { 3320 PetscErrorCode ierr; 3321 Vec b,x; 3322 PetscInt m,N,i; 3323 PetscScalar *bb,*xx; 3324 3325 PetscFunctionBegin; 3326 ierr = MatDenseGetArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr); 3327 ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr); 3328 ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr); /* number local rows */ 3329 ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr); /* total columns in dense matrix */ 3330 ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr); 3331 for (i=0; i<N; i++) { 3332 ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr); 3333 ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr); 3334 if (trans) { 3335 ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr); 3336 } else { 3337 ierr = MatSolve(A,b,x);CHKERRQ(ierr); 3338 } 3339 ierr = VecResetArray(x);CHKERRQ(ierr); 3340 ierr = VecResetArray(b);CHKERRQ(ierr); 3341 } 3342 ierr = VecDestroy(&b);CHKERRQ(ierr); 3343 ierr = VecDestroy(&x);CHKERRQ(ierr); 3344 ierr = MatDenseRestoreArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr); 3345 ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr); 3346 PetscFunctionReturn(0); 3347 } 3348 3349 /*@ 3350 MatMatSolve - Solves A X = B, given a factored matrix. 3351 3352 Neighbor-wise Collective on Mat 3353 3354 Input Parameters: 3355 + A - the factored matrix 3356 - B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS) 3357 3358 Output Parameter: 3359 . X - the result matrix (dense matrix) 3360 3361 Notes: 3362 If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B); 3363 otherwise, B and X cannot be the same. 3364 3365 Notes: 3366 Most users should usually employ the simplified KSP interface for linear solvers 3367 instead of working directly with matrix algebra routines such as this. 3368 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3369 at a time. 3370 3371 Level: developer 3372 3373 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3374 @*/ 3375 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3376 { 3377 PetscErrorCode ierr; 3378 3379 PetscFunctionBegin; 3380 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3381 PetscValidType(A,1); 3382 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3383 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3384 PetscCheckSameComm(A,1,B,2); 3385 PetscCheckSameComm(A,1,X,3); 3386 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); 3387 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); 3388 if (X->cmap->N != B->cmap->N) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3389 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3390 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3391 MatCheckPreallocated(A,1); 3392 3393 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3394 if (!A->ops->matsolve) { 3395 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3396 ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr); 3397 } else { 3398 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr); 3399 } 3400 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3401 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3402 PetscFunctionReturn(0); 3403 } 3404 3405 /*@ 3406 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3407 3408 Neighbor-wise Collective on Mat 3409 3410 Input Parameters: 3411 + A - the factored matrix 3412 - B - the right-hand-side matrix (dense matrix) 3413 3414 Output Parameter: 3415 . X - the result matrix (dense matrix) 3416 3417 Notes: 3418 The matrices B and X cannot be the same. I.e., one cannot 3419 call MatMatSolveTranspose(A,X,X). 3420 3421 Notes: 3422 Most users should usually employ the simplified KSP interface for linear solvers 3423 instead of working directly with matrix algebra routines such as this. 3424 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3425 at a time. 3426 3427 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3428 3429 Level: developer 3430 3431 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor() 3432 @*/ 3433 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3434 { 3435 PetscErrorCode ierr; 3436 3437 PetscFunctionBegin; 3438 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3439 PetscValidType(A,1); 3440 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3441 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3442 PetscCheckSameComm(A,1,B,2); 3443 PetscCheckSameComm(A,1,X,3); 3444 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3445 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); 3446 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); 3447 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); 3448 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"); 3449 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3450 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3451 MatCheckPreallocated(A,1); 3452 3453 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3454 if (!A->ops->matsolvetranspose) { 3455 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3456 ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr); 3457 } else { 3458 ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr); 3459 } 3460 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3461 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3462 PetscFunctionReturn(0); 3463 } 3464 3465 /*@ 3466 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3467 3468 Neighbor-wise Collective on Mat 3469 3470 Input Parameters: 3471 + A - the factored matrix 3472 - Bt - the transpose of right-hand-side matrix 3473 3474 Output Parameter: 3475 . X - the result matrix (dense matrix) 3476 3477 Notes: 3478 Most users should usually employ the simplified KSP interface for linear solvers 3479 instead of working directly with matrix algebra routines such as this. 3480 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3481 at a time. 3482 3483 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(). 3484 3485 Level: developer 3486 3487 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3488 @*/ 3489 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3490 { 3491 PetscErrorCode ierr; 3492 3493 PetscFunctionBegin; 3494 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3495 PetscValidType(A,1); 3496 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3497 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3498 PetscCheckSameComm(A,1,Bt,2); 3499 PetscCheckSameComm(A,1,X,3); 3500 3501 if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3502 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); 3503 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); 3504 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"); 3505 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3506 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3507 MatCheckPreallocated(A,1); 3508 3509 if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3510 ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3511 ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr); 3512 ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3513 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3514 PetscFunctionReturn(0); 3515 } 3516 3517 /*@ 3518 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3519 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3520 3521 Neighbor-wise Collective on Mat 3522 3523 Input Parameters: 3524 + mat - the factored matrix 3525 - b - the right-hand-side vector 3526 3527 Output Parameter: 3528 . x - the result vector 3529 3530 Notes: 3531 MatSolve() should be used for most applications, as it performs 3532 a forward solve followed by a backward solve. 3533 3534 The vectors b and x cannot be the same, i.e., one cannot 3535 call MatForwardSolve(A,x,x). 3536 3537 For matrix in seqsbaij format with block size larger than 1, 3538 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3539 MatForwardSolve() solves U^T*D y = b, and 3540 MatBackwardSolve() solves U x = y. 3541 Thus they do not provide a symmetric preconditioner. 3542 3543 Most users should employ the simplified KSP interface for linear solvers 3544 instead of working directly with matrix algebra routines such as this. 3545 See, e.g., KSPCreate(). 3546 3547 Level: developer 3548 3549 .seealso: MatSolve(), MatBackwardSolve() 3550 @*/ 3551 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3552 { 3553 PetscErrorCode ierr; 3554 3555 PetscFunctionBegin; 3556 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3557 PetscValidType(mat,1); 3558 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3559 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3560 PetscCheckSameComm(mat,1,b,2); 3561 PetscCheckSameComm(mat,1,x,3); 3562 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3563 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); 3564 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); 3565 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); 3566 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3567 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3568 MatCheckPreallocated(mat,1); 3569 3570 if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3571 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3572 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 3573 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3574 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3575 PetscFunctionReturn(0); 3576 } 3577 3578 /*@ 3579 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3580 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3581 3582 Neighbor-wise Collective on Mat 3583 3584 Input Parameters: 3585 + mat - the factored matrix 3586 - b - the right-hand-side vector 3587 3588 Output Parameter: 3589 . x - the result vector 3590 3591 Notes: 3592 MatSolve() should be used for most applications, as it performs 3593 a forward solve followed by a backward solve. 3594 3595 The vectors b and x cannot be the same. I.e., one cannot 3596 call MatBackwardSolve(A,x,x). 3597 3598 For matrix in seqsbaij format with block size larger than 1, 3599 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3600 MatForwardSolve() solves U^T*D y = b, and 3601 MatBackwardSolve() solves U x = y. 3602 Thus they do not provide a symmetric preconditioner. 3603 3604 Most users should employ the simplified KSP interface for linear solvers 3605 instead of working directly with matrix algebra routines such as this. 3606 See, e.g., KSPCreate(). 3607 3608 Level: developer 3609 3610 .seealso: MatSolve(), MatForwardSolve() 3611 @*/ 3612 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3613 { 3614 PetscErrorCode ierr; 3615 3616 PetscFunctionBegin; 3617 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3618 PetscValidType(mat,1); 3619 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3620 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3621 PetscCheckSameComm(mat,1,b,2); 3622 PetscCheckSameComm(mat,1,x,3); 3623 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3624 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); 3625 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); 3626 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); 3627 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3628 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3629 MatCheckPreallocated(mat,1); 3630 3631 if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3632 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3633 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 3634 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3635 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3636 PetscFunctionReturn(0); 3637 } 3638 3639 /*@ 3640 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3641 3642 Neighbor-wise Collective on Mat 3643 3644 Input Parameters: 3645 + mat - the factored matrix 3646 . b - the right-hand-side vector 3647 - y - the vector to be added to 3648 3649 Output Parameter: 3650 . x - the result vector 3651 3652 Notes: 3653 The vectors b and x cannot be the same. I.e., one cannot 3654 call MatSolveAdd(A,x,y,x). 3655 3656 Most users should employ the simplified KSP interface for linear solvers 3657 instead of working directly with matrix algebra routines such as this. 3658 See, e.g., KSPCreate(). 3659 3660 Level: developer 3661 3662 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3663 @*/ 3664 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3665 { 3666 PetscScalar one = 1.0; 3667 Vec tmp; 3668 PetscErrorCode ierr; 3669 3670 PetscFunctionBegin; 3671 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3672 PetscValidType(mat,1); 3673 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3674 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3675 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3676 PetscCheckSameComm(mat,1,b,2); 3677 PetscCheckSameComm(mat,1,y,2); 3678 PetscCheckSameComm(mat,1,x,3); 3679 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3680 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); 3681 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); 3682 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); 3683 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); 3684 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); 3685 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3686 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3687 MatCheckPreallocated(mat,1); 3688 3689 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3690 if (mat->ops->solveadd) { 3691 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 3692 } else { 3693 /* do the solve then the add manually */ 3694 if (x != y) { 3695 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3696 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3697 } else { 3698 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3699 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3700 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3701 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3702 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3703 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3704 } 3705 } 3706 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3707 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3708 PetscFunctionReturn(0); 3709 } 3710 3711 /*@ 3712 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3713 3714 Neighbor-wise Collective on Mat 3715 3716 Input Parameters: 3717 + mat - the factored matrix 3718 - b - the right-hand-side vector 3719 3720 Output Parameter: 3721 . x - the result vector 3722 3723 Notes: 3724 The vectors b and x cannot be the same. I.e., one cannot 3725 call MatSolveTranspose(A,x,x). 3726 3727 Most users should employ the simplified KSP interface for linear solvers 3728 instead of working directly with matrix algebra routines such as this. 3729 See, e.g., KSPCreate(). 3730 3731 Level: developer 3732 3733 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 3734 @*/ 3735 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3736 { 3737 PetscErrorCode ierr; 3738 3739 PetscFunctionBegin; 3740 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3741 PetscValidType(mat,1); 3742 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3743 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3744 PetscCheckSameComm(mat,1,b,2); 3745 PetscCheckSameComm(mat,1,x,3); 3746 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3747 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); 3748 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); 3749 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3750 MatCheckPreallocated(mat,1); 3751 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3752 if (mat->factorerrortype) { 3753 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3754 ierr = VecSetInf(x);CHKERRQ(ierr); 3755 } else { 3756 if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3757 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr); 3758 } 3759 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3760 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3761 PetscFunctionReturn(0); 3762 } 3763 3764 /*@ 3765 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3766 factored matrix. 3767 3768 Neighbor-wise Collective on Mat 3769 3770 Input Parameters: 3771 + mat - the factored matrix 3772 . b - the right-hand-side vector 3773 - y - the vector to be added to 3774 3775 Output Parameter: 3776 . x - the result vector 3777 3778 Notes: 3779 The vectors b and x cannot be the same. I.e., one cannot 3780 call MatSolveTransposeAdd(A,x,y,x). 3781 3782 Most users should employ the simplified KSP interface for linear solvers 3783 instead of working directly with matrix algebra routines such as this. 3784 See, e.g., KSPCreate(). 3785 3786 Level: developer 3787 3788 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 3789 @*/ 3790 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 3791 { 3792 PetscScalar one = 1.0; 3793 PetscErrorCode ierr; 3794 Vec tmp; 3795 3796 PetscFunctionBegin; 3797 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3798 PetscValidType(mat,1); 3799 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3800 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3801 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3802 PetscCheckSameComm(mat,1,b,2); 3803 PetscCheckSameComm(mat,1,y,3); 3804 PetscCheckSameComm(mat,1,x,4); 3805 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3806 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); 3807 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); 3808 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); 3809 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); 3810 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3811 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3812 MatCheckPreallocated(mat,1); 3813 3814 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3815 if (mat->ops->solvetransposeadd) { 3816 if (mat->factorerrortype) { 3817 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3818 ierr = VecSetInf(x);CHKERRQ(ierr); 3819 } else { 3820 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr); 3821 } 3822 } else { 3823 /* do the solve then the add manually */ 3824 if (x != y) { 3825 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3826 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3827 } else { 3828 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3829 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3830 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3831 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3832 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3833 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3834 } 3835 } 3836 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3837 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3838 PetscFunctionReturn(0); 3839 } 3840 /* ----------------------------------------------------------------*/ 3841 3842 /*@ 3843 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3844 3845 Neighbor-wise Collective on Mat 3846 3847 Input Parameters: 3848 + mat - the matrix 3849 . b - the right hand side 3850 . omega - the relaxation factor 3851 . flag - flag indicating the type of SOR (see below) 3852 . shift - diagonal shift 3853 . its - the number of iterations 3854 - lits - the number of local iterations 3855 3856 Output Parameters: 3857 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 3858 3859 SOR Flags: 3860 + SOR_FORWARD_SWEEP - forward SOR 3861 . SOR_BACKWARD_SWEEP - backward SOR 3862 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 3863 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 3864 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 3865 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 3866 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 3867 upper/lower triangular part of matrix to 3868 vector (with omega) 3869 - SOR_ZERO_INITIAL_GUESS - zero initial guess 3870 3871 Notes: 3872 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 3873 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 3874 on each processor. 3875 3876 Application programmers will not generally use MatSOR() directly, 3877 but instead will employ the KSP/PC interface. 3878 3879 Notes: 3880 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 3881 3882 Notes for Advanced Users: 3883 The flags are implemented as bitwise inclusive or operations. 3884 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 3885 to specify a zero initial guess for SSOR. 3886 3887 Most users should employ the simplified KSP interface for linear solvers 3888 instead of working directly with matrix algebra routines such as this. 3889 See, e.g., KSPCreate(). 3890 3891 Vectors x and b CANNOT be the same 3892 3893 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 3894 3895 Level: developer 3896 3897 @*/ 3898 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 3899 { 3900 PetscErrorCode ierr; 3901 3902 PetscFunctionBegin; 3903 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3904 PetscValidType(mat,1); 3905 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3906 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 3907 PetscCheckSameComm(mat,1,b,2); 3908 PetscCheckSameComm(mat,1,x,8); 3909 if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3910 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3911 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3912 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); 3913 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); 3914 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); 3915 if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its); 3916 if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits); 3917 if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 3918 3919 MatCheckPreallocated(mat,1); 3920 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3921 ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 3922 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3923 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3924 PetscFunctionReturn(0); 3925 } 3926 3927 /* 3928 Default matrix copy routine. 3929 */ 3930 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 3931 { 3932 PetscErrorCode ierr; 3933 PetscInt i,rstart = 0,rend = 0,nz; 3934 const PetscInt *cwork; 3935 const PetscScalar *vwork; 3936 3937 PetscFunctionBegin; 3938 if (B->assembled) { 3939 ierr = MatZeroEntries(B);CHKERRQ(ierr); 3940 } 3941 if (str == SAME_NONZERO_PATTERN) { 3942 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 3943 for (i=rstart; i<rend; i++) { 3944 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3945 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 3946 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3947 } 3948 } else { 3949 ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr); 3950 } 3951 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3952 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3953 PetscFunctionReturn(0); 3954 } 3955 3956 /*@ 3957 MatCopy - Copies a matrix to another matrix. 3958 3959 Collective on Mat 3960 3961 Input Parameters: 3962 + A - the matrix 3963 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 3964 3965 Output Parameter: 3966 . B - where the copy is put 3967 3968 Notes: 3969 If you use SAME_NONZERO_PATTERN then the two matrices had better have the 3970 same nonzero pattern or the routine will crash. 3971 3972 MatCopy() copies the matrix entries of a matrix to another existing 3973 matrix (after first zeroing the second matrix). A related routine is 3974 MatConvert(), which first creates a new matrix and then copies the data. 3975 3976 Level: intermediate 3977 3978 .seealso: MatConvert(), MatDuplicate() 3979 3980 @*/ 3981 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 3982 { 3983 PetscErrorCode ierr; 3984 PetscInt i; 3985 3986 PetscFunctionBegin; 3987 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3988 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3989 PetscValidType(A,1); 3990 PetscValidType(B,2); 3991 PetscCheckSameComm(A,1,B,2); 3992 MatCheckPreallocated(B,2); 3993 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3994 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3995 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); 3996 MatCheckPreallocated(A,1); 3997 if (A == B) PetscFunctionReturn(0); 3998 3999 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4000 if (A->ops->copy) { 4001 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 4002 } else { /* generic conversion */ 4003 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 4004 } 4005 4006 B->stencil.dim = A->stencil.dim; 4007 B->stencil.noc = A->stencil.noc; 4008 for (i=0; i<=A->stencil.dim; i++) { 4009 B->stencil.dims[i] = A->stencil.dims[i]; 4010 B->stencil.starts[i] = A->stencil.starts[i]; 4011 } 4012 4013 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4014 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4015 PetscFunctionReturn(0); 4016 } 4017 4018 /*@C 4019 MatConvert - Converts a matrix to another matrix, either of the same 4020 or different type. 4021 4022 Collective on Mat 4023 4024 Input Parameters: 4025 + mat - the matrix 4026 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4027 same type as the original matrix. 4028 - reuse - denotes if the destination matrix is to be created or reused. 4029 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 4030 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). 4031 4032 Output Parameter: 4033 . M - pointer to place new matrix 4034 4035 Notes: 4036 MatConvert() first creates a new matrix and then copies the data from 4037 the first matrix. A related routine is MatCopy(), which copies the matrix 4038 entries of one matrix to another already existing matrix context. 4039 4040 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4041 the MPI communicator of the generated matrix is always the same as the communicator 4042 of the input matrix. 4043 4044 Level: intermediate 4045 4046 .seealso: MatCopy(), MatDuplicate() 4047 @*/ 4048 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M) 4049 { 4050 PetscErrorCode ierr; 4051 PetscBool sametype,issame,flg,issymmetric,ishermitian; 4052 char convname[256],mtype[256]; 4053 Mat B; 4054 4055 PetscFunctionBegin; 4056 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4057 PetscValidType(mat,1); 4058 PetscValidPointer(M,3); 4059 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4060 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4061 MatCheckPreallocated(mat,1); 4062 4063 ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr); 4064 if (flg) newtype = mtype; 4065 4066 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 4067 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 4068 if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4069 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"); 4070 4071 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4072 ierr = PetscInfo3(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr); 4073 PetscFunctionReturn(0); 4074 } 4075 4076 /* Cache Mat options because some converter use MatHeaderReplace */ 4077 issymmetric = mat->symmetric; 4078 ishermitian = mat->hermitian; 4079 4080 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4081 ierr = PetscInfo3(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr); 4082 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4083 } else { 4084 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4085 const char *prefix[3] = {"seq","mpi",""}; 4086 PetscInt i; 4087 /* 4088 Order of precedence: 4089 0) See if newtype is a superclass of the current matrix. 4090 1) See if a specialized converter is known to the current matrix. 4091 2) See if a specialized converter is known to the desired matrix class. 4092 3) See if a good general converter is registered for the desired class 4093 (as of 6/27/03 only MATMPIADJ falls into this category). 4094 4) See if a good general converter is known for the current matrix. 4095 5) Use a really basic converter. 4096 */ 4097 4098 /* 0) See if newtype is a superclass of the current matrix. 4099 i.e mat is mpiaij and newtype is aij */ 4100 for (i=0; i<2; i++) { 4101 ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4102 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4103 ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr); 4104 ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr); 4105 if (flg) { 4106 if (reuse == MAT_INPLACE_MATRIX) { 4107 PetscFunctionReturn(0); 4108 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4109 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4110 PetscFunctionReturn(0); 4111 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4112 ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4113 PetscFunctionReturn(0); 4114 } 4115 } 4116 } 4117 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4118 for (i=0; i<3; i++) { 4119 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4120 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4121 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4122 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4123 ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr); 4124 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4125 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr); 4126 ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4127 if (conv) goto foundconv; 4128 } 4129 4130 /* 2) See if a specialized converter is known to the desired matrix class. */ 4131 ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 4132 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr); 4133 ierr = MatSetType(B,newtype);CHKERRQ(ierr); 4134 for (i=0; i<3; i++) { 4135 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4136 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4137 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4138 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4139 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4140 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4141 ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 4142 ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4143 if (conv) { 4144 ierr = MatDestroy(&B);CHKERRQ(ierr); 4145 goto foundconv; 4146 } 4147 } 4148 4149 /* 3) See if a good general converter is registered for the desired class */ 4150 conv = B->ops->convertfrom; 4151 ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4152 ierr = MatDestroy(&B);CHKERRQ(ierr); 4153 if (conv) goto foundconv; 4154 4155 /* 4) See if a good general converter is known for the current matrix */ 4156 if (mat->ops->convert) { 4157 conv = mat->ops->convert; 4158 } 4159 ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4160 if (conv) goto foundconv; 4161 4162 /* 5) Use a really basic converter. */ 4163 ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr); 4164 conv = MatConvert_Basic; 4165 4166 foundconv: 4167 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4168 ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr); 4169 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4170 /* the block sizes must be same if the mappings are copied over */ 4171 (*M)->rmap->bs = mat->rmap->bs; 4172 (*M)->cmap->bs = mat->cmap->bs; 4173 ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr); 4174 ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr); 4175 (*M)->rmap->mapping = mat->rmap->mapping; 4176 (*M)->cmap->mapping = mat->cmap->mapping; 4177 } 4178 (*M)->stencil.dim = mat->stencil.dim; 4179 (*M)->stencil.noc = mat->stencil.noc; 4180 for (i=0; i<=mat->stencil.dim; i++) { 4181 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4182 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4183 } 4184 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4185 } 4186 ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr); 4187 4188 /* Copy Mat options */ 4189 if (issymmetric) { 4190 ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 4191 } 4192 if (ishermitian) { 4193 ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 4194 } 4195 PetscFunctionReturn(0); 4196 } 4197 4198 /*@C 4199 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4200 4201 Not Collective 4202 4203 Input Parameter: 4204 . mat - the matrix, must be a factored matrix 4205 4206 Output Parameter: 4207 . type - the string name of the package (do not free this string) 4208 4209 Notes: 4210 In Fortran you pass in a empty string and the package name will be copied into it. 4211 (Make sure the string is long enough) 4212 4213 Level: intermediate 4214 4215 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4216 @*/ 4217 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4218 { 4219 PetscErrorCode ierr, (*conv)(Mat,MatSolverType*); 4220 4221 PetscFunctionBegin; 4222 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4223 PetscValidType(mat,1); 4224 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4225 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr); 4226 if (!conv) { 4227 *type = MATSOLVERPETSC; 4228 } else { 4229 ierr = (*conv)(mat,type);CHKERRQ(ierr); 4230 } 4231 PetscFunctionReturn(0); 4232 } 4233 4234 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4235 struct _MatSolverTypeForSpecifcType { 4236 MatType mtype; 4237 PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*); 4238 MatSolverTypeForSpecifcType next; 4239 }; 4240 4241 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4242 struct _MatSolverTypeHolder { 4243 char *name; 4244 MatSolverTypeForSpecifcType handlers; 4245 MatSolverTypeHolder next; 4246 }; 4247 4248 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4249 4250 /*@C 4251 MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type 4252 4253 Input Parameters: 4254 + package - name of the package, for example petsc or superlu 4255 . mtype - the matrix type that works with this package 4256 . ftype - the type of factorization supported by the package 4257 - getfactor - routine that will create the factored matrix ready to be used 4258 4259 Level: intermediate 4260 4261 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4262 @*/ 4263 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*)) 4264 { 4265 PetscErrorCode ierr; 4266 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4267 PetscBool flg; 4268 MatSolverTypeForSpecifcType inext,iprev = NULL; 4269 4270 PetscFunctionBegin; 4271 ierr = MatInitializePackage();CHKERRQ(ierr); 4272 if (!next) { 4273 ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr); 4274 ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr); 4275 ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr); 4276 ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr); 4277 MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor; 4278 PetscFunctionReturn(0); 4279 } 4280 while (next) { 4281 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4282 if (flg) { 4283 if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4284 inext = next->handlers; 4285 while (inext) { 4286 ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4287 if (flg) { 4288 inext->getfactor[(int)ftype-1] = getfactor; 4289 PetscFunctionReturn(0); 4290 } 4291 iprev = inext; 4292 inext = inext->next; 4293 } 4294 ierr = PetscNew(&iprev->next);CHKERRQ(ierr); 4295 ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr); 4296 iprev->next->getfactor[(int)ftype-1] = getfactor; 4297 PetscFunctionReturn(0); 4298 } 4299 prev = next; 4300 next = next->next; 4301 } 4302 ierr = PetscNew(&prev->next);CHKERRQ(ierr); 4303 ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr); 4304 ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr); 4305 ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr); 4306 prev->next->handlers->getfactor[(int)ftype-1] = getfactor; 4307 PetscFunctionReturn(0); 4308 } 4309 4310 /*@C 4311 MatSolvePackageGet - Get's the function that creates the factor matrix if it exist 4312 4313 Input Parameters: 4314 + package - name of the package, for example petsc or superlu 4315 . ftype - the type of factorization supported by the package 4316 - mtype - the matrix type that works with this package 4317 4318 Output Parameters: 4319 + foundpackage - PETSC_TRUE if the package was registered 4320 . foundmtype - PETSC_TRUE if the package supports the requested mtype 4321 - getfactor - routine that will create the factored matrix ready to be used or NULL if not found 4322 4323 Level: intermediate 4324 4325 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4326 @*/ 4327 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*)) 4328 { 4329 PetscErrorCode ierr; 4330 MatSolverTypeHolder next = MatSolverTypeHolders; 4331 PetscBool flg; 4332 MatSolverTypeForSpecifcType inext; 4333 4334 PetscFunctionBegin; 4335 if (foundpackage) *foundpackage = PETSC_FALSE; 4336 if (foundmtype) *foundmtype = PETSC_FALSE; 4337 if (getfactor) *getfactor = NULL; 4338 4339 if (package) { 4340 while (next) { 4341 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4342 if (flg) { 4343 if (foundpackage) *foundpackage = PETSC_TRUE; 4344 inext = next->handlers; 4345 while (inext) { 4346 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4347 if (flg) { 4348 if (foundmtype) *foundmtype = PETSC_TRUE; 4349 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4350 PetscFunctionReturn(0); 4351 } 4352 inext = inext->next; 4353 } 4354 } 4355 next = next->next; 4356 } 4357 } else { 4358 while (next) { 4359 inext = next->handlers; 4360 while (inext) { 4361 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4362 if (flg && inext->getfactor[(int)ftype-1]) { 4363 if (foundpackage) *foundpackage = PETSC_TRUE; 4364 if (foundmtype) *foundmtype = PETSC_TRUE; 4365 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4366 PetscFunctionReturn(0); 4367 } 4368 inext = inext->next; 4369 } 4370 next = next->next; 4371 } 4372 } 4373 PetscFunctionReturn(0); 4374 } 4375 4376 PetscErrorCode MatSolverTypeDestroy(void) 4377 { 4378 PetscErrorCode ierr; 4379 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4380 MatSolverTypeForSpecifcType inext,iprev; 4381 4382 PetscFunctionBegin; 4383 while (next) { 4384 ierr = PetscFree(next->name);CHKERRQ(ierr); 4385 inext = next->handlers; 4386 while (inext) { 4387 ierr = PetscFree(inext->mtype);CHKERRQ(ierr); 4388 iprev = inext; 4389 inext = inext->next; 4390 ierr = PetscFree(iprev);CHKERRQ(ierr); 4391 } 4392 prev = next; 4393 next = next->next; 4394 ierr = PetscFree(prev);CHKERRQ(ierr); 4395 } 4396 MatSolverTypeHolders = NULL; 4397 PetscFunctionReturn(0); 4398 } 4399 4400 /*@C 4401 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4402 4403 Collective on Mat 4404 4405 Input Parameters: 4406 + mat - the matrix 4407 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4408 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4409 4410 Output Parameters: 4411 . f - the factor matrix used with MatXXFactorSymbolic() calls 4412 4413 Notes: 4414 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4415 such as pastix, superlu, mumps etc. 4416 4417 PETSc must have been ./configure to use the external solver, using the option --download-package 4418 4419 Level: intermediate 4420 4421 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4422 @*/ 4423 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4424 { 4425 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*); 4426 PetscBool foundpackage,foundmtype; 4427 4428 PetscFunctionBegin; 4429 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4430 PetscValidType(mat,1); 4431 4432 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4433 MatCheckPreallocated(mat,1); 4434 4435 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr); 4436 if (!foundpackage) { 4437 if (type) { 4438 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type); 4439 } else { 4440 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>"); 4441 } 4442 } 4443 4444 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4445 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); 4446 4447 #if defined(PETSC_USE_COMPLEX) 4448 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"); 4449 #endif 4450 4451 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4452 PetscFunctionReturn(0); 4453 } 4454 4455 /*@C 4456 MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type 4457 4458 Not Collective 4459 4460 Input Parameters: 4461 + mat - the matrix 4462 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4463 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4464 4465 Output Parameter: 4466 . flg - PETSC_TRUE if the factorization is available 4467 4468 Notes: 4469 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4470 such as pastix, superlu, mumps etc. 4471 4472 PETSc must have been ./configure to use the external solver, using the option --download-package 4473 4474 Level: intermediate 4475 4476 .seealso: MatCopy(), MatDuplicate(), MatGetFactor() 4477 @*/ 4478 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4479 { 4480 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4481 4482 PetscFunctionBegin; 4483 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4484 PetscValidType(mat,1); 4485 4486 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4487 MatCheckPreallocated(mat,1); 4488 4489 *flg = PETSC_FALSE; 4490 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4491 if (gconv) { 4492 *flg = PETSC_TRUE; 4493 } 4494 PetscFunctionReturn(0); 4495 } 4496 4497 #include <petscdmtypes.h> 4498 4499 /*@ 4500 MatDuplicate - Duplicates a matrix including the non-zero structure. 4501 4502 Collective on Mat 4503 4504 Input Parameters: 4505 + mat - the matrix 4506 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4507 See the manual page for MatDuplicateOption for an explanation of these options. 4508 4509 Output Parameter: 4510 . M - pointer to place new matrix 4511 4512 Level: intermediate 4513 4514 Notes: 4515 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4516 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. 4517 4518 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4519 @*/ 4520 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4521 { 4522 PetscErrorCode ierr; 4523 Mat B; 4524 PetscInt i; 4525 DM dm; 4526 void (*viewf)(void); 4527 4528 PetscFunctionBegin; 4529 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4530 PetscValidType(mat,1); 4531 PetscValidPointer(M,3); 4532 if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4533 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4534 MatCheckPreallocated(mat,1); 4535 4536 *M = 0; 4537 if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type"); 4538 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4539 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4540 B = *M; 4541 4542 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr); 4543 if (viewf) { 4544 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr); 4545 } 4546 4547 B->stencil.dim = mat->stencil.dim; 4548 B->stencil.noc = mat->stencil.noc; 4549 for (i=0; i<=mat->stencil.dim; i++) { 4550 B->stencil.dims[i] = mat->stencil.dims[i]; 4551 B->stencil.starts[i] = mat->stencil.starts[i]; 4552 } 4553 4554 B->nooffproczerorows = mat->nooffproczerorows; 4555 B->nooffprocentries = mat->nooffprocentries; 4556 4557 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr); 4558 if (dm) { 4559 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 4560 } 4561 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4562 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4563 PetscFunctionReturn(0); 4564 } 4565 4566 /*@ 4567 MatGetDiagonal - Gets the diagonal of a matrix. 4568 4569 Logically Collective on Mat 4570 4571 Input Parameters: 4572 + mat - the matrix 4573 - v - the vector for storing the diagonal 4574 4575 Output Parameter: 4576 . v - the diagonal of the matrix 4577 4578 Level: intermediate 4579 4580 Note: 4581 Currently only correct in parallel for square matrices. 4582 4583 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4584 @*/ 4585 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4586 { 4587 PetscErrorCode ierr; 4588 4589 PetscFunctionBegin; 4590 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4591 PetscValidType(mat,1); 4592 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4593 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4594 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4595 MatCheckPreallocated(mat,1); 4596 4597 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4598 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4599 PetscFunctionReturn(0); 4600 } 4601 4602 /*@C 4603 MatGetRowMin - Gets the minimum value (of the real part) of each 4604 row of the matrix 4605 4606 Logically Collective on Mat 4607 4608 Input Parameters: 4609 . mat - the matrix 4610 4611 Output Parameter: 4612 + v - the vector for storing the maximums 4613 - idx - the indices of the column found for each row (optional) 4614 4615 Level: intermediate 4616 4617 Notes: 4618 The result of this call are the same as if one converted the matrix to dense format 4619 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4620 4621 This code is only implemented for a couple of matrix formats. 4622 4623 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4624 MatGetRowMax() 4625 @*/ 4626 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4627 { 4628 PetscErrorCode ierr; 4629 4630 PetscFunctionBegin; 4631 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4632 PetscValidType(mat,1); 4633 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4634 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4635 if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4636 MatCheckPreallocated(mat,1); 4637 4638 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4639 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4640 PetscFunctionReturn(0); 4641 } 4642 4643 /*@C 4644 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4645 row of the matrix 4646 4647 Logically Collective on Mat 4648 4649 Input Parameters: 4650 . mat - the matrix 4651 4652 Output Parameter: 4653 + v - the vector for storing the minimums 4654 - idx - the indices of the column found for each row (or NULL if not needed) 4655 4656 Level: intermediate 4657 4658 Notes: 4659 if a row is completely empty or has only 0.0 values then the idx[] value for that 4660 row is 0 (the first column). 4661 4662 This code is only implemented for a couple of matrix formats. 4663 4664 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4665 @*/ 4666 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4667 { 4668 PetscErrorCode ierr; 4669 4670 PetscFunctionBegin; 4671 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4672 PetscValidType(mat,1); 4673 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4674 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4675 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4676 MatCheckPreallocated(mat,1); 4677 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 4678 4679 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4680 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4681 PetscFunctionReturn(0); 4682 } 4683 4684 /*@C 4685 MatGetRowMax - Gets the maximum value (of the real part) of each 4686 row of the matrix 4687 4688 Logically Collective on Mat 4689 4690 Input Parameters: 4691 . mat - the matrix 4692 4693 Output Parameter: 4694 + v - the vector for storing the maximums 4695 - idx - the indices of the column found for each row (optional) 4696 4697 Level: intermediate 4698 4699 Notes: 4700 The result of this call are the same as if one converted the matrix to dense format 4701 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4702 4703 This code is only implemented for a couple of matrix formats. 4704 4705 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4706 @*/ 4707 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4708 { 4709 PetscErrorCode ierr; 4710 4711 PetscFunctionBegin; 4712 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4713 PetscValidType(mat,1); 4714 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4715 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4716 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4717 MatCheckPreallocated(mat,1); 4718 4719 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4720 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4721 PetscFunctionReturn(0); 4722 } 4723 4724 /*@C 4725 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4726 row of the matrix 4727 4728 Logically Collective on Mat 4729 4730 Input Parameters: 4731 . mat - the matrix 4732 4733 Output Parameter: 4734 + v - the vector for storing the maximums 4735 - idx - the indices of the column found for each row (or NULL if not needed) 4736 4737 Level: intermediate 4738 4739 Notes: 4740 if a row is completely empty or has only 0.0 values then the idx[] value for that 4741 row is 0 (the first column). 4742 4743 This code is only implemented for a couple of matrix formats. 4744 4745 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4746 @*/ 4747 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4748 { 4749 PetscErrorCode ierr; 4750 4751 PetscFunctionBegin; 4752 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4753 PetscValidType(mat,1); 4754 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4755 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4756 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4757 MatCheckPreallocated(mat,1); 4758 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 4759 4760 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4761 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4762 PetscFunctionReturn(0); 4763 } 4764 4765 /*@ 4766 MatGetRowSum - Gets the sum of each row of the matrix 4767 4768 Logically or Neighborhood Collective on Mat 4769 4770 Input Parameters: 4771 . mat - the matrix 4772 4773 Output Parameter: 4774 . v - the vector for storing the sum of rows 4775 4776 Level: intermediate 4777 4778 Notes: 4779 This code is slow since it is not currently specialized for different formats 4780 4781 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4782 @*/ 4783 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4784 { 4785 Vec ones; 4786 PetscErrorCode ierr; 4787 4788 PetscFunctionBegin; 4789 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4790 PetscValidType(mat,1); 4791 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4792 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4793 MatCheckPreallocated(mat,1); 4794 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr); 4795 ierr = VecSet(ones,1.);CHKERRQ(ierr); 4796 ierr = MatMult(mat,ones,v);CHKERRQ(ierr); 4797 ierr = VecDestroy(&ones);CHKERRQ(ierr); 4798 PetscFunctionReturn(0); 4799 } 4800 4801 /*@ 4802 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4803 4804 Collective on Mat 4805 4806 Input Parameter: 4807 + mat - the matrix to transpose 4808 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 4809 4810 Output Parameters: 4811 . B - the transpose 4812 4813 Notes: 4814 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 4815 4816 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 4817 4818 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4819 4820 Level: intermediate 4821 4822 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4823 @*/ 4824 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4825 { 4826 PetscErrorCode ierr; 4827 4828 PetscFunctionBegin; 4829 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4830 PetscValidType(mat,1); 4831 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4832 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4833 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4834 if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 4835 if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 4836 MatCheckPreallocated(mat,1); 4837 4838 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4839 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 4840 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4841 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 4842 PetscFunctionReturn(0); 4843 } 4844 4845 /*@ 4846 MatIsTranspose - Test whether a matrix is another one's transpose, 4847 or its own, in which case it tests symmetry. 4848 4849 Collective on Mat 4850 4851 Input Parameter: 4852 + A - the matrix to test 4853 - B - the matrix to test against, this can equal the first parameter 4854 4855 Output Parameters: 4856 . flg - the result 4857 4858 Notes: 4859 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4860 has a running time of the order of the number of nonzeros; the parallel 4861 test involves parallel copies of the block-offdiagonal parts of the matrix. 4862 4863 Level: intermediate 4864 4865 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 4866 @*/ 4867 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4868 { 4869 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4870 4871 PetscFunctionBegin; 4872 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4873 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4874 PetscValidBoolPointer(flg,3); 4875 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 4876 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 4877 *flg = PETSC_FALSE; 4878 if (f && g) { 4879 if (f == g) { 4880 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4881 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 4882 } else { 4883 MatType mattype; 4884 if (!f) { 4885 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 4886 } else { 4887 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 4888 } 4889 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype); 4890 } 4891 PetscFunctionReturn(0); 4892 } 4893 4894 /*@ 4895 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 4896 4897 Collective on Mat 4898 4899 Input Parameter: 4900 + mat - the matrix to transpose and complex conjugate 4901 - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose 4902 4903 Output Parameters: 4904 . B - the Hermitian 4905 4906 Level: intermediate 4907 4908 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4909 @*/ 4910 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 4911 { 4912 PetscErrorCode ierr; 4913 4914 PetscFunctionBegin; 4915 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 4916 #if defined(PETSC_USE_COMPLEX) 4917 ierr = MatConjugate(*B);CHKERRQ(ierr); 4918 #endif 4919 PetscFunctionReturn(0); 4920 } 4921 4922 /*@ 4923 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 4924 4925 Collective on Mat 4926 4927 Input Parameter: 4928 + A - the matrix to test 4929 - B - the matrix to test against, this can equal the first parameter 4930 4931 Output Parameters: 4932 . flg - the result 4933 4934 Notes: 4935 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4936 has a running time of the order of the number of nonzeros; the parallel 4937 test involves parallel copies of the block-offdiagonal parts of the matrix. 4938 4939 Level: intermediate 4940 4941 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 4942 @*/ 4943 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4944 { 4945 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4946 4947 PetscFunctionBegin; 4948 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4949 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4950 PetscValidBoolPointer(flg,3); 4951 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 4952 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 4953 if (f && g) { 4954 if (f==g) { 4955 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4956 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 4957 } 4958 PetscFunctionReturn(0); 4959 } 4960 4961 /*@ 4962 MatPermute - Creates a new matrix with rows and columns permuted from the 4963 original. 4964 4965 Collective on Mat 4966 4967 Input Parameters: 4968 + mat - the matrix to permute 4969 . row - row permutation, each processor supplies only the permutation for its rows 4970 - col - column permutation, each processor supplies only the permutation for its columns 4971 4972 Output Parameters: 4973 . B - the permuted matrix 4974 4975 Level: advanced 4976 4977 Note: 4978 The index sets map from row/col of permuted matrix to row/col of original matrix. 4979 The index sets should be on the same communicator as Mat and have the same local sizes. 4980 4981 .seealso: MatGetOrdering(), ISAllGather() 4982 4983 @*/ 4984 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 4985 { 4986 PetscErrorCode ierr; 4987 4988 PetscFunctionBegin; 4989 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4990 PetscValidType(mat,1); 4991 PetscValidHeaderSpecific(row,IS_CLASSID,2); 4992 PetscValidHeaderSpecific(col,IS_CLASSID,3); 4993 PetscValidPointer(B,4); 4994 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4995 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4996 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 4997 MatCheckPreallocated(mat,1); 4998 4999 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 5000 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 5001 PetscFunctionReturn(0); 5002 } 5003 5004 /*@ 5005 MatEqual - Compares two matrices. 5006 5007 Collective on Mat 5008 5009 Input Parameters: 5010 + A - the first matrix 5011 - B - the second matrix 5012 5013 Output Parameter: 5014 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5015 5016 Level: intermediate 5017 5018 @*/ 5019 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5020 { 5021 PetscErrorCode ierr; 5022 5023 PetscFunctionBegin; 5024 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5025 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5026 PetscValidType(A,1); 5027 PetscValidType(B,2); 5028 PetscValidBoolPointer(flg,3); 5029 PetscCheckSameComm(A,1,B,2); 5030 MatCheckPreallocated(B,2); 5031 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5032 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5033 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); 5034 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5035 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 5036 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); 5037 MatCheckPreallocated(A,1); 5038 5039 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 5040 PetscFunctionReturn(0); 5041 } 5042 5043 /*@ 5044 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5045 matrices that are stored as vectors. Either of the two scaling 5046 matrices can be NULL. 5047 5048 Collective on Mat 5049 5050 Input Parameters: 5051 + mat - the matrix to be scaled 5052 . l - the left scaling vector (or NULL) 5053 - r - the right scaling vector (or NULL) 5054 5055 Notes: 5056 MatDiagonalScale() computes A = LAR, where 5057 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5058 The L scales the rows of the matrix, the R scales the columns of the matrix. 5059 5060 Level: intermediate 5061 5062 5063 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5064 @*/ 5065 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5066 { 5067 PetscErrorCode ierr; 5068 5069 PetscFunctionBegin; 5070 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5071 PetscValidType(mat,1); 5072 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5073 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5074 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5075 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5076 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5077 MatCheckPreallocated(mat,1); 5078 5079 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5080 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 5081 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5082 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5083 PetscFunctionReturn(0); 5084 } 5085 5086 /*@ 5087 MatScale - Scales all elements of a matrix by a given number. 5088 5089 Logically Collective on Mat 5090 5091 Input Parameters: 5092 + mat - the matrix to be scaled 5093 - a - the scaling value 5094 5095 Output Parameter: 5096 . mat - the scaled matrix 5097 5098 Level: intermediate 5099 5100 .seealso: MatDiagonalScale() 5101 @*/ 5102 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5103 { 5104 PetscErrorCode ierr; 5105 5106 PetscFunctionBegin; 5107 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5108 PetscValidType(mat,1); 5109 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5110 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5111 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5112 PetscValidLogicalCollectiveScalar(mat,a,2); 5113 MatCheckPreallocated(mat,1); 5114 5115 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5116 if (a != (PetscScalar)1.0) { 5117 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5118 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5119 } 5120 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5121 PetscFunctionReturn(0); 5122 } 5123 5124 /*@ 5125 MatNorm - Calculates various norms of a matrix. 5126 5127 Collective on Mat 5128 5129 Input Parameters: 5130 + mat - the matrix 5131 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5132 5133 Output Parameters: 5134 . nrm - the resulting norm 5135 5136 Level: intermediate 5137 5138 @*/ 5139 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5140 { 5141 PetscErrorCode ierr; 5142 5143 PetscFunctionBegin; 5144 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5145 PetscValidType(mat,1); 5146 PetscValidScalarPointer(nrm,3); 5147 5148 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5149 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5150 if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5151 MatCheckPreallocated(mat,1); 5152 5153 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5154 PetscFunctionReturn(0); 5155 } 5156 5157 /* 5158 This variable is used to prevent counting of MatAssemblyBegin() that 5159 are called from within a MatAssemblyEnd(). 5160 */ 5161 static PetscInt MatAssemblyEnd_InUse = 0; 5162 /*@ 5163 MatAssemblyBegin - Begins assembling the matrix. This routine should 5164 be called after completing all calls to MatSetValues(). 5165 5166 Collective on Mat 5167 5168 Input Parameters: 5169 + mat - the matrix 5170 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5171 5172 Notes: 5173 MatSetValues() generally caches the values. The matrix is ready to 5174 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5175 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5176 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5177 using the matrix. 5178 5179 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5180 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 5181 a global collective operation requring all processes that share the matrix. 5182 5183 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5184 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5185 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5186 5187 Level: beginner 5188 5189 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5190 @*/ 5191 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5192 { 5193 PetscErrorCode ierr; 5194 5195 PetscFunctionBegin; 5196 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5197 PetscValidType(mat,1); 5198 MatCheckPreallocated(mat,1); 5199 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5200 if (mat->assembled) { 5201 mat->was_assembled = PETSC_TRUE; 5202 mat->assembled = PETSC_FALSE; 5203 } 5204 5205 if (!MatAssemblyEnd_InUse) { 5206 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5207 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5208 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5209 } else if (mat->ops->assemblybegin) { 5210 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5211 } 5212 PetscFunctionReturn(0); 5213 } 5214 5215 /*@ 5216 MatAssembled - Indicates if a matrix has been assembled and is ready for 5217 use; for example, in matrix-vector product. 5218 5219 Not Collective 5220 5221 Input Parameter: 5222 . mat - the matrix 5223 5224 Output Parameter: 5225 . assembled - PETSC_TRUE or PETSC_FALSE 5226 5227 Level: advanced 5228 5229 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5230 @*/ 5231 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5232 { 5233 PetscFunctionBegin; 5234 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5235 PetscValidPointer(assembled,2); 5236 *assembled = mat->assembled; 5237 PetscFunctionReturn(0); 5238 } 5239 5240 /*@ 5241 MatAssemblyEnd - Completes assembling the matrix. This routine should 5242 be called after MatAssemblyBegin(). 5243 5244 Collective on Mat 5245 5246 Input Parameters: 5247 + mat - the matrix 5248 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5249 5250 Options Database Keys: 5251 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5252 . -mat_view ::ascii_info_detail - Prints more detailed info 5253 . -mat_view - Prints matrix in ASCII format 5254 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5255 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5256 . -display <name> - Sets display name (default is host) 5257 . -draw_pause <sec> - Sets number of seconds to pause after display 5258 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab ) 5259 . -viewer_socket_machine <machine> - Machine to use for socket 5260 . -viewer_socket_port <port> - Port number to use for socket 5261 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5262 5263 Notes: 5264 MatSetValues() generally caches the values. The matrix is ready to 5265 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5266 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5267 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5268 using the matrix. 5269 5270 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5271 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5272 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5273 5274 Level: beginner 5275 5276 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5277 @*/ 5278 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5279 { 5280 PetscErrorCode ierr; 5281 static PetscInt inassm = 0; 5282 PetscBool flg = PETSC_FALSE; 5283 5284 PetscFunctionBegin; 5285 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5286 PetscValidType(mat,1); 5287 5288 inassm++; 5289 MatAssemblyEnd_InUse++; 5290 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5291 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5292 if (mat->ops->assemblyend) { 5293 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5294 } 5295 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5296 } else if (mat->ops->assemblyend) { 5297 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5298 } 5299 5300 /* Flush assembly is not a true assembly */ 5301 if (type != MAT_FLUSH_ASSEMBLY) { 5302 mat->num_ass++; 5303 mat->assembled = PETSC_TRUE; 5304 mat->ass_nonzerostate = mat->nonzerostate; 5305 } 5306 5307 mat->insertmode = NOT_SET_VALUES; 5308 MatAssemblyEnd_InUse--; 5309 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5310 if (!mat->symmetric_eternal) { 5311 mat->symmetric_set = PETSC_FALSE; 5312 mat->hermitian_set = PETSC_FALSE; 5313 mat->structurally_symmetric_set = PETSC_FALSE; 5314 } 5315 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5316 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5317 5318 if (mat->checksymmetryonassembly) { 5319 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5320 if (flg) { 5321 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5322 } else { 5323 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5324 } 5325 } 5326 if (mat->nullsp && mat->checknullspaceonassembly) { 5327 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5328 } 5329 } 5330 inassm--; 5331 PetscFunctionReturn(0); 5332 } 5333 5334 /*@ 5335 MatSetOption - Sets a parameter option for a matrix. Some options 5336 may be specific to certain storage formats. Some options 5337 determine how values will be inserted (or added). Sorted, 5338 row-oriented input will generally assemble the fastest. The default 5339 is row-oriented. 5340 5341 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5342 5343 Input Parameters: 5344 + mat - the matrix 5345 . option - the option, one of those listed below (and possibly others), 5346 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5347 5348 Options Describing Matrix Structure: 5349 + MAT_SPD - symmetric positive definite 5350 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5351 . MAT_HERMITIAN - transpose is the complex conjugation 5352 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5353 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5354 you set to be kept with all future use of the matrix 5355 including after MatAssemblyBegin/End() which could 5356 potentially change the symmetry structure, i.e. you 5357 KNOW the matrix will ALWAYS have the property you set. 5358 5359 5360 Options For Use with MatSetValues(): 5361 Insert a logically dense subblock, which can be 5362 . MAT_ROW_ORIENTED - row-oriented (default) 5363 5364 Note these options reflect the data you pass in with MatSetValues(); it has 5365 nothing to do with how the data is stored internally in the matrix 5366 data structure. 5367 5368 When (re)assembling a matrix, we can restrict the input for 5369 efficiency/debugging purposes. These options include: 5370 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5371 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 5372 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5373 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5374 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5375 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5376 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5377 performance for very large process counts. 5378 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5379 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5380 functions, instead sending only neighbor messages. 5381 5382 Notes: 5383 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5384 5385 Some options are relevant only for particular matrix types and 5386 are thus ignored by others. Other options are not supported by 5387 certain matrix types and will generate an error message if set. 5388 5389 If using a Fortran 77 module to compute a matrix, one may need to 5390 use the column-oriented option (or convert to the row-oriented 5391 format). 5392 5393 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5394 that would generate a new entry in the nonzero structure is instead 5395 ignored. Thus, if memory has not alredy been allocated for this particular 5396 data, then the insertion is ignored. For dense matrices, in which 5397 the entire array is allocated, no entries are ever ignored. 5398 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5399 5400 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5401 that would generate a new entry in the nonzero structure instead produces 5402 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 5403 5404 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5405 that would generate a new entry that has not been preallocated will 5406 instead produce an error. (Currently supported for AIJ and BAIJ formats 5407 only.) This is a useful flag when debugging matrix memory preallocation. 5408 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5409 5410 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5411 other processors should be dropped, rather than stashed. 5412 This is useful if you know that the "owning" processor is also 5413 always generating the correct matrix entries, so that PETSc need 5414 not transfer duplicate entries generated on another processor. 5415 5416 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5417 searches during matrix assembly. When this flag is set, the hash table 5418 is created during the first Matrix Assembly. This hash table is 5419 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5420 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5421 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5422 supported by MATMPIBAIJ format only. 5423 5424 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5425 are kept in the nonzero structure 5426 5427 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5428 a zero location in the matrix 5429 5430 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5431 5432 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5433 zero row routines and thus improves performance for very large process counts. 5434 5435 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5436 part of the matrix (since they should match the upper triangular part). 5437 5438 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5439 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5440 with finite difference schemes with non-periodic boundary conditions. 5441 Notes: 5442 Can only be called after MatSetSizes() and MatSetType() have been set. 5443 5444 Level: intermediate 5445 5446 .seealso: MatOption, Mat 5447 5448 @*/ 5449 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5450 { 5451 PetscErrorCode ierr; 5452 5453 PetscFunctionBegin; 5454 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5455 PetscValidType(mat,1); 5456 if (op > 0) { 5457 PetscValidLogicalCollectiveEnum(mat,op,2); 5458 PetscValidLogicalCollectiveBool(mat,flg,3); 5459 } 5460 5461 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); 5462 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()"); 5463 5464 switch (op) { 5465 case MAT_NO_OFF_PROC_ENTRIES: 5466 mat->nooffprocentries = flg; 5467 PetscFunctionReturn(0); 5468 break; 5469 case MAT_SUBSET_OFF_PROC_ENTRIES: 5470 mat->assembly_subset = flg; 5471 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5472 #if !defined(PETSC_HAVE_MPIUNI) 5473 ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr); 5474 #endif 5475 mat->stash.first_assembly_done = PETSC_FALSE; 5476 } 5477 PetscFunctionReturn(0); 5478 case MAT_NO_OFF_PROC_ZERO_ROWS: 5479 mat->nooffproczerorows = flg; 5480 PetscFunctionReturn(0); 5481 break; 5482 case MAT_SPD: 5483 mat->spd_set = PETSC_TRUE; 5484 mat->spd = flg; 5485 if (flg) { 5486 mat->symmetric = PETSC_TRUE; 5487 mat->structurally_symmetric = PETSC_TRUE; 5488 mat->symmetric_set = PETSC_TRUE; 5489 mat->structurally_symmetric_set = PETSC_TRUE; 5490 } 5491 break; 5492 case MAT_SYMMETRIC: 5493 mat->symmetric = flg; 5494 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5495 mat->symmetric_set = PETSC_TRUE; 5496 mat->structurally_symmetric_set = flg; 5497 #if !defined(PETSC_USE_COMPLEX) 5498 mat->hermitian = flg; 5499 mat->hermitian_set = PETSC_TRUE; 5500 #endif 5501 break; 5502 case MAT_HERMITIAN: 5503 mat->hermitian = flg; 5504 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5505 mat->hermitian_set = PETSC_TRUE; 5506 mat->structurally_symmetric_set = flg; 5507 #if !defined(PETSC_USE_COMPLEX) 5508 mat->symmetric = flg; 5509 mat->symmetric_set = PETSC_TRUE; 5510 #endif 5511 break; 5512 case MAT_STRUCTURALLY_SYMMETRIC: 5513 mat->structurally_symmetric = flg; 5514 mat->structurally_symmetric_set = PETSC_TRUE; 5515 break; 5516 case MAT_SYMMETRY_ETERNAL: 5517 mat->symmetric_eternal = flg; 5518 break; 5519 case MAT_STRUCTURE_ONLY: 5520 mat->structure_only = flg; 5521 break; 5522 case MAT_SORTED_FULL: 5523 mat->sortedfull = flg; 5524 break; 5525 default: 5526 break; 5527 } 5528 if (mat->ops->setoption) { 5529 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5530 } 5531 PetscFunctionReturn(0); 5532 } 5533 5534 /*@ 5535 MatGetOption - Gets a parameter option that has been set for a matrix. 5536 5537 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5538 5539 Input Parameters: 5540 + mat - the matrix 5541 - option - the option, this only responds to certain options, check the code for which ones 5542 5543 Output Parameter: 5544 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5545 5546 Notes: 5547 Can only be called after MatSetSizes() and MatSetType() have been set. 5548 5549 Level: intermediate 5550 5551 .seealso: MatOption, MatSetOption() 5552 5553 @*/ 5554 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5555 { 5556 PetscFunctionBegin; 5557 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5558 PetscValidType(mat,1); 5559 5560 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); 5561 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()"); 5562 5563 switch (op) { 5564 case MAT_NO_OFF_PROC_ENTRIES: 5565 *flg = mat->nooffprocentries; 5566 break; 5567 case MAT_NO_OFF_PROC_ZERO_ROWS: 5568 *flg = mat->nooffproczerorows; 5569 break; 5570 case MAT_SYMMETRIC: 5571 *flg = mat->symmetric; 5572 break; 5573 case MAT_HERMITIAN: 5574 *flg = mat->hermitian; 5575 break; 5576 case MAT_STRUCTURALLY_SYMMETRIC: 5577 *flg = mat->structurally_symmetric; 5578 break; 5579 case MAT_SYMMETRY_ETERNAL: 5580 *flg = mat->symmetric_eternal; 5581 break; 5582 case MAT_SPD: 5583 *flg = mat->spd; 5584 break; 5585 default: 5586 break; 5587 } 5588 PetscFunctionReturn(0); 5589 } 5590 5591 /*@ 5592 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5593 this routine retains the old nonzero structure. 5594 5595 Logically Collective on Mat 5596 5597 Input Parameters: 5598 . mat - the matrix 5599 5600 Level: intermediate 5601 5602 Notes: 5603 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. 5604 See the Performance chapter of the users manual for information on preallocating matrices. 5605 5606 .seealso: MatZeroRows() 5607 @*/ 5608 PetscErrorCode MatZeroEntries(Mat mat) 5609 { 5610 PetscErrorCode ierr; 5611 5612 PetscFunctionBegin; 5613 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5614 PetscValidType(mat,1); 5615 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5616 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"); 5617 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5618 MatCheckPreallocated(mat,1); 5619 5620 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5621 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5622 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5623 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5624 PetscFunctionReturn(0); 5625 } 5626 5627 /*@ 5628 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5629 of a set of rows and columns of a matrix. 5630 5631 Collective on Mat 5632 5633 Input Parameters: 5634 + mat - the matrix 5635 . numRows - the number of rows to remove 5636 . rows - the global row indices 5637 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5638 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5639 - b - optional vector of right hand side, that will be adjusted by provided solution 5640 5641 Notes: 5642 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5643 5644 The user can set a value in the diagonal entry (or for the AIJ and 5645 row formats can optionally remove the main diagonal entry from the 5646 nonzero structure as well, by passing 0.0 as the final argument). 5647 5648 For the parallel case, all processes that share the matrix (i.e., 5649 those in the communicator used for matrix creation) MUST call this 5650 routine, regardless of whether any rows being zeroed are owned by 5651 them. 5652 5653 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5654 list only rows local to itself). 5655 5656 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5657 5658 Level: intermediate 5659 5660 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5661 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5662 @*/ 5663 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5664 { 5665 PetscErrorCode ierr; 5666 5667 PetscFunctionBegin; 5668 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5669 PetscValidType(mat,1); 5670 if (numRows) PetscValidIntPointer(rows,3); 5671 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5672 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5673 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5674 MatCheckPreallocated(mat,1); 5675 5676 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5677 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5678 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5679 PetscFunctionReturn(0); 5680 } 5681 5682 /*@ 5683 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5684 of a set of rows and columns of a matrix. 5685 5686 Collective on Mat 5687 5688 Input Parameters: 5689 + mat - the matrix 5690 . is - the rows to zero 5691 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5692 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5693 - b - optional vector of right hand side, that will be adjusted by provided solution 5694 5695 Notes: 5696 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5697 5698 The user can set a value in the diagonal entry (or for the AIJ and 5699 row formats can optionally remove the main diagonal entry from the 5700 nonzero structure as well, by passing 0.0 as the final argument). 5701 5702 For the parallel case, all processes that share the matrix (i.e., 5703 those in the communicator used for matrix creation) MUST call this 5704 routine, regardless of whether any rows being zeroed are owned by 5705 them. 5706 5707 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5708 list only rows local to itself). 5709 5710 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5711 5712 Level: intermediate 5713 5714 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5715 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 5716 @*/ 5717 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5718 { 5719 PetscErrorCode ierr; 5720 PetscInt numRows; 5721 const PetscInt *rows; 5722 5723 PetscFunctionBegin; 5724 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5725 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5726 PetscValidType(mat,1); 5727 PetscValidType(is,2); 5728 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5729 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5730 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5731 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5732 PetscFunctionReturn(0); 5733 } 5734 5735 /*@ 5736 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5737 of a set of rows of a matrix. 5738 5739 Collective on Mat 5740 5741 Input Parameters: 5742 + mat - the matrix 5743 . numRows - the number of rows to remove 5744 . rows - the global row indices 5745 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5746 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5747 - b - optional vector of right hand side, that will be adjusted by provided solution 5748 5749 Notes: 5750 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5751 but does not release memory. For the dense and block diagonal 5752 formats this does not alter the nonzero structure. 5753 5754 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5755 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5756 merely zeroed. 5757 5758 The user can set a value in the diagonal entry (or for the AIJ and 5759 row formats can optionally remove the main diagonal entry from the 5760 nonzero structure as well, by passing 0.0 as the final argument). 5761 5762 For the parallel case, all processes that share the matrix (i.e., 5763 those in the communicator used for matrix creation) MUST call this 5764 routine, regardless of whether any rows being zeroed are owned by 5765 them. 5766 5767 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5768 list only rows local to itself). 5769 5770 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5771 owns that are to be zeroed. This saves a global synchronization in the implementation. 5772 5773 Level: intermediate 5774 5775 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5776 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5777 @*/ 5778 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5779 { 5780 PetscErrorCode ierr; 5781 5782 PetscFunctionBegin; 5783 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5784 PetscValidType(mat,1); 5785 if (numRows) PetscValidIntPointer(rows,3); 5786 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5787 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5788 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5789 MatCheckPreallocated(mat,1); 5790 5791 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5792 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5793 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5794 PetscFunctionReturn(0); 5795 } 5796 5797 /*@ 5798 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5799 of a set of rows of a matrix. 5800 5801 Collective on Mat 5802 5803 Input Parameters: 5804 + mat - the matrix 5805 . is - index set of rows to remove 5806 . diag - value put in all diagonals of eliminated rows 5807 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5808 - b - optional vector of right hand side, that will be adjusted by provided solution 5809 5810 Notes: 5811 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5812 but does not release memory. For the dense and block diagonal 5813 formats this does not alter the nonzero structure. 5814 5815 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5816 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5817 merely zeroed. 5818 5819 The user can set a value in the diagonal entry (or for the AIJ and 5820 row formats can optionally remove the main diagonal entry from the 5821 nonzero structure as well, by passing 0.0 as the final argument). 5822 5823 For the parallel case, all processes that share the matrix (i.e., 5824 those in the communicator used for matrix creation) MUST call this 5825 routine, regardless of whether any rows being zeroed are owned by 5826 them. 5827 5828 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5829 list only rows local to itself). 5830 5831 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5832 owns that are to be zeroed. This saves a global synchronization in the implementation. 5833 5834 Level: intermediate 5835 5836 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5837 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5838 @*/ 5839 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5840 { 5841 PetscInt numRows; 5842 const PetscInt *rows; 5843 PetscErrorCode ierr; 5844 5845 PetscFunctionBegin; 5846 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5847 PetscValidType(mat,1); 5848 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5849 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5850 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5851 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5852 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5853 PetscFunctionReturn(0); 5854 } 5855 5856 /*@ 5857 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 5858 of a set of rows of a matrix. These rows must be local to the process. 5859 5860 Collective on Mat 5861 5862 Input Parameters: 5863 + mat - the matrix 5864 . numRows - the number of rows to remove 5865 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5866 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5867 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5868 - b - optional vector of right hand side, that will be adjusted by provided solution 5869 5870 Notes: 5871 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5872 but does not release memory. For the dense and block diagonal 5873 formats this does not alter the nonzero structure. 5874 5875 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5876 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5877 merely zeroed. 5878 5879 The user can set a value in the diagonal entry (or for the AIJ and 5880 row formats can optionally remove the main diagonal entry from the 5881 nonzero structure as well, by passing 0.0 as the final argument). 5882 5883 For the parallel case, all processes that share the matrix (i.e., 5884 those in the communicator used for matrix creation) MUST call this 5885 routine, regardless of whether any rows being zeroed are owned by 5886 them. 5887 5888 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5889 list only rows local to itself). 5890 5891 The grid coordinates are across the entire grid, not just the local portion 5892 5893 In Fortran idxm and idxn should be declared as 5894 $ MatStencil idxm(4,m) 5895 and the values inserted using 5896 $ idxm(MatStencil_i,1) = i 5897 $ idxm(MatStencil_j,1) = j 5898 $ idxm(MatStencil_k,1) = k 5899 $ idxm(MatStencil_c,1) = c 5900 etc 5901 5902 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5903 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5904 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5905 DM_BOUNDARY_PERIODIC boundary type. 5906 5907 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 5908 a single value per point) you can skip filling those indices. 5909 5910 Level: intermediate 5911 5912 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5913 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5914 @*/ 5915 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5916 { 5917 PetscInt dim = mat->stencil.dim; 5918 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5919 PetscInt *dims = mat->stencil.dims+1; 5920 PetscInt *starts = mat->stencil.starts; 5921 PetscInt *dxm = (PetscInt*) rows; 5922 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5923 PetscErrorCode ierr; 5924 5925 PetscFunctionBegin; 5926 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5927 PetscValidType(mat,1); 5928 if (numRows) PetscValidIntPointer(rows,3); 5929 5930 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 5931 for (i = 0; i < numRows; ++i) { 5932 /* Skip unused dimensions (they are ordered k, j, i, c) */ 5933 for (j = 0; j < 3-sdim; ++j) dxm++; 5934 /* Local index in X dir */ 5935 tmp = *dxm++ - starts[0]; 5936 /* Loop over remaining dimensions */ 5937 for (j = 0; j < dim-1; ++j) { 5938 /* If nonlocal, set index to be negative */ 5939 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 5940 /* Update local index */ 5941 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 5942 } 5943 /* Skip component slot if necessary */ 5944 if (mat->stencil.noc) dxm++; 5945 /* Local row number */ 5946 if (tmp >= 0) { 5947 jdxm[numNewRows++] = tmp; 5948 } 5949 } 5950 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 5951 ierr = PetscFree(jdxm);CHKERRQ(ierr); 5952 PetscFunctionReturn(0); 5953 } 5954 5955 /*@ 5956 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 5957 of a set of rows and columns of a matrix. 5958 5959 Collective on Mat 5960 5961 Input Parameters: 5962 + mat - the matrix 5963 . numRows - the number of rows/columns to remove 5964 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5965 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5966 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5967 - b - optional vector of right hand side, that will be adjusted by provided solution 5968 5969 Notes: 5970 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5971 but does not release memory. For the dense and block diagonal 5972 formats this does not alter the nonzero structure. 5973 5974 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5975 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5976 merely zeroed. 5977 5978 The user can set a value in the diagonal entry (or for the AIJ and 5979 row formats can optionally remove the main diagonal entry from the 5980 nonzero structure as well, by passing 0.0 as the final argument). 5981 5982 For the parallel case, all processes that share the matrix (i.e., 5983 those in the communicator used for matrix creation) MUST call this 5984 routine, regardless of whether any rows being zeroed are owned by 5985 them. 5986 5987 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5988 list only rows local to itself, but the row/column numbers are given in local numbering). 5989 5990 The grid coordinates are across the entire grid, not just the local portion 5991 5992 In Fortran idxm and idxn should be declared as 5993 $ MatStencil idxm(4,m) 5994 and the values inserted using 5995 $ idxm(MatStencil_i,1) = i 5996 $ idxm(MatStencil_j,1) = j 5997 $ idxm(MatStencil_k,1) = k 5998 $ idxm(MatStencil_c,1) = c 5999 etc 6000 6001 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6002 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6003 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6004 DM_BOUNDARY_PERIODIC boundary type. 6005 6006 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 6007 a single value per point) you can skip filling those indices. 6008 6009 Level: intermediate 6010 6011 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6012 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 6013 @*/ 6014 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6015 { 6016 PetscInt dim = mat->stencil.dim; 6017 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6018 PetscInt *dims = mat->stencil.dims+1; 6019 PetscInt *starts = mat->stencil.starts; 6020 PetscInt *dxm = (PetscInt*) rows; 6021 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6022 PetscErrorCode ierr; 6023 6024 PetscFunctionBegin; 6025 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6026 PetscValidType(mat,1); 6027 if (numRows) PetscValidIntPointer(rows,3); 6028 6029 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6030 for (i = 0; i < numRows; ++i) { 6031 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6032 for (j = 0; j < 3-sdim; ++j) dxm++; 6033 /* Local index in X dir */ 6034 tmp = *dxm++ - starts[0]; 6035 /* Loop over remaining dimensions */ 6036 for (j = 0; j < dim-1; ++j) { 6037 /* If nonlocal, set index to be negative */ 6038 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6039 /* Update local index */ 6040 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6041 } 6042 /* Skip component slot if necessary */ 6043 if (mat->stencil.noc) dxm++; 6044 /* Local row number */ 6045 if (tmp >= 0) { 6046 jdxm[numNewRows++] = tmp; 6047 } 6048 } 6049 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6050 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6051 PetscFunctionReturn(0); 6052 } 6053 6054 /*@C 6055 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6056 of a set of rows of a matrix; using local numbering of rows. 6057 6058 Collective on Mat 6059 6060 Input Parameters: 6061 + mat - the matrix 6062 . numRows - the number of rows to remove 6063 . rows - the global row indices 6064 . diag - value put in all diagonals of eliminated rows 6065 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6066 - b - optional vector of right hand side, that will be adjusted by provided solution 6067 6068 Notes: 6069 Before calling MatZeroRowsLocal(), the user must first set the 6070 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6071 6072 For the AIJ matrix formats this removes the old nonzero structure, 6073 but does not release memory. For the dense and block diagonal 6074 formats this does not alter the nonzero structure. 6075 6076 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6077 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6078 merely zeroed. 6079 6080 The user can set a value in the diagonal entry (or for the AIJ and 6081 row formats can optionally remove the main diagonal entry from the 6082 nonzero structure as well, by passing 0.0 as the final argument). 6083 6084 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6085 owns that are to be zeroed. This saves a global synchronization in the implementation. 6086 6087 Level: intermediate 6088 6089 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6090 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6091 @*/ 6092 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6093 { 6094 PetscErrorCode ierr; 6095 6096 PetscFunctionBegin; 6097 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6098 PetscValidType(mat,1); 6099 if (numRows) PetscValidIntPointer(rows,3); 6100 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6101 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6102 MatCheckPreallocated(mat,1); 6103 6104 if (mat->ops->zerorowslocal) { 6105 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6106 } else { 6107 IS is, newis; 6108 const PetscInt *newRows; 6109 6110 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6111 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6112 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 6113 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6114 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6115 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6116 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6117 ierr = ISDestroy(&is);CHKERRQ(ierr); 6118 } 6119 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6120 PetscFunctionReturn(0); 6121 } 6122 6123 /*@ 6124 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6125 of a set of rows of a matrix; using local numbering of rows. 6126 6127 Collective on Mat 6128 6129 Input Parameters: 6130 + mat - the matrix 6131 . is - index set of rows to remove 6132 . diag - value put in all diagonals of eliminated rows 6133 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6134 - b - optional vector of right hand side, that will be adjusted by provided solution 6135 6136 Notes: 6137 Before calling MatZeroRowsLocalIS(), the user must first set the 6138 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6139 6140 For the AIJ matrix formats this removes the old nonzero structure, 6141 but does not release memory. For the dense and block diagonal 6142 formats this does not alter the nonzero structure. 6143 6144 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6145 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6146 merely zeroed. 6147 6148 The user can set a value in the diagonal entry (or for the AIJ and 6149 row formats can optionally remove the main diagonal entry from the 6150 nonzero structure as well, by passing 0.0 as the final argument). 6151 6152 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6153 owns that are to be zeroed. This saves a global synchronization in the implementation. 6154 6155 Level: intermediate 6156 6157 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6158 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6159 @*/ 6160 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6161 { 6162 PetscErrorCode ierr; 6163 PetscInt numRows; 6164 const PetscInt *rows; 6165 6166 PetscFunctionBegin; 6167 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6168 PetscValidType(mat,1); 6169 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6170 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6171 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6172 MatCheckPreallocated(mat,1); 6173 6174 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6175 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6176 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6177 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6178 PetscFunctionReturn(0); 6179 } 6180 6181 /*@ 6182 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6183 of a set of rows and columns of a matrix; using local numbering of rows. 6184 6185 Collective on Mat 6186 6187 Input Parameters: 6188 + mat - the matrix 6189 . numRows - the number of rows to remove 6190 . rows - the global row indices 6191 . diag - value put in all diagonals of eliminated rows 6192 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6193 - b - optional vector of right hand side, that will be adjusted by provided solution 6194 6195 Notes: 6196 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6197 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6198 6199 The user can set a value in the diagonal entry (or for the AIJ and 6200 row formats can optionally remove the main diagonal entry from the 6201 nonzero structure as well, by passing 0.0 as the final argument). 6202 6203 Level: intermediate 6204 6205 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6206 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6207 @*/ 6208 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6209 { 6210 PetscErrorCode ierr; 6211 IS is, newis; 6212 const PetscInt *newRows; 6213 6214 PetscFunctionBegin; 6215 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6216 PetscValidType(mat,1); 6217 if (numRows) PetscValidIntPointer(rows,3); 6218 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6219 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6220 MatCheckPreallocated(mat,1); 6221 6222 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6223 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6224 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6225 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6226 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6227 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6228 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6229 ierr = ISDestroy(&is);CHKERRQ(ierr); 6230 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6231 PetscFunctionReturn(0); 6232 } 6233 6234 /*@ 6235 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6236 of a set of rows and columns of a matrix; using local numbering of rows. 6237 6238 Collective on Mat 6239 6240 Input Parameters: 6241 + mat - the matrix 6242 . is - index set of rows to remove 6243 . diag - value put in all diagonals of eliminated rows 6244 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6245 - b - optional vector of right hand side, that will be adjusted by provided solution 6246 6247 Notes: 6248 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6249 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6250 6251 The user can set a value in the diagonal entry (or for the AIJ and 6252 row formats can optionally remove the main diagonal entry from the 6253 nonzero structure as well, by passing 0.0 as the final argument). 6254 6255 Level: intermediate 6256 6257 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6258 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6259 @*/ 6260 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6261 { 6262 PetscErrorCode ierr; 6263 PetscInt numRows; 6264 const PetscInt *rows; 6265 6266 PetscFunctionBegin; 6267 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6268 PetscValidType(mat,1); 6269 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6270 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6271 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6272 MatCheckPreallocated(mat,1); 6273 6274 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6275 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6276 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6277 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6278 PetscFunctionReturn(0); 6279 } 6280 6281 /*@C 6282 MatGetSize - Returns the numbers of rows and columns in a matrix. 6283 6284 Not Collective 6285 6286 Input Parameter: 6287 . mat - the matrix 6288 6289 Output Parameters: 6290 + m - the number of global rows 6291 - n - the number of global columns 6292 6293 Note: both output parameters can be NULL on input. 6294 6295 Level: beginner 6296 6297 .seealso: MatGetLocalSize() 6298 @*/ 6299 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6300 { 6301 PetscFunctionBegin; 6302 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6303 if (m) *m = mat->rmap->N; 6304 if (n) *n = mat->cmap->N; 6305 PetscFunctionReturn(0); 6306 } 6307 6308 /*@C 6309 MatGetLocalSize - Returns the number of rows and columns in a matrix 6310 stored locally. This information may be implementation dependent, so 6311 use with care. 6312 6313 Not Collective 6314 6315 Input Parameters: 6316 . mat - the matrix 6317 6318 Output Parameters: 6319 + m - the number of local rows 6320 - n - the number of local columns 6321 6322 Note: both output parameters can be NULL on input. 6323 6324 Level: beginner 6325 6326 .seealso: MatGetSize() 6327 @*/ 6328 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6329 { 6330 PetscFunctionBegin; 6331 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6332 if (m) PetscValidIntPointer(m,2); 6333 if (n) PetscValidIntPointer(n,3); 6334 if (m) *m = mat->rmap->n; 6335 if (n) *n = mat->cmap->n; 6336 PetscFunctionReturn(0); 6337 } 6338 6339 /*@C 6340 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6341 this processor. (The columns of the "diagonal block") 6342 6343 Not Collective, unless matrix has not been allocated, then collective on Mat 6344 6345 Input Parameters: 6346 . mat - the matrix 6347 6348 Output Parameters: 6349 + m - the global index of the first local column 6350 - n - one more than the global index of the last local column 6351 6352 Notes: 6353 both output parameters can be NULL on input. 6354 6355 Level: developer 6356 6357 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6358 6359 @*/ 6360 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6361 { 6362 PetscFunctionBegin; 6363 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6364 PetscValidType(mat,1); 6365 if (m) PetscValidIntPointer(m,2); 6366 if (n) PetscValidIntPointer(n,3); 6367 MatCheckPreallocated(mat,1); 6368 if (m) *m = mat->cmap->rstart; 6369 if (n) *n = mat->cmap->rend; 6370 PetscFunctionReturn(0); 6371 } 6372 6373 /*@C 6374 MatGetOwnershipRange - Returns the range of matrix rows owned by 6375 this processor, assuming that the matrix is laid out with the first 6376 n1 rows on the first processor, the next n2 rows on the second, etc. 6377 For certain parallel layouts this range may not be well defined. 6378 6379 Not Collective 6380 6381 Input Parameters: 6382 . mat - the matrix 6383 6384 Output Parameters: 6385 + m - the global index of the first local row 6386 - n - one more than the global index of the last local row 6387 6388 Note: Both output parameters can be NULL on input. 6389 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6390 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6391 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6392 6393 Level: beginner 6394 6395 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6396 6397 @*/ 6398 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6399 { 6400 PetscFunctionBegin; 6401 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6402 PetscValidType(mat,1); 6403 if (m) PetscValidIntPointer(m,2); 6404 if (n) PetscValidIntPointer(n,3); 6405 MatCheckPreallocated(mat,1); 6406 if (m) *m = mat->rmap->rstart; 6407 if (n) *n = mat->rmap->rend; 6408 PetscFunctionReturn(0); 6409 } 6410 6411 /*@C 6412 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6413 each process 6414 6415 Not Collective, unless matrix has not been allocated, then collective on Mat 6416 6417 Input Parameters: 6418 . mat - the matrix 6419 6420 Output Parameters: 6421 . ranges - start of each processors portion plus one more than the total length at the end 6422 6423 Level: beginner 6424 6425 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6426 6427 @*/ 6428 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6429 { 6430 PetscErrorCode ierr; 6431 6432 PetscFunctionBegin; 6433 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6434 PetscValidType(mat,1); 6435 MatCheckPreallocated(mat,1); 6436 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6437 PetscFunctionReturn(0); 6438 } 6439 6440 /*@C 6441 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6442 this processor. (The columns of the "diagonal blocks" for each process) 6443 6444 Not Collective, unless matrix has not been allocated, then collective on Mat 6445 6446 Input Parameters: 6447 . mat - the matrix 6448 6449 Output Parameters: 6450 . ranges - start of each processors portion plus one more then the total length at the end 6451 6452 Level: beginner 6453 6454 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6455 6456 @*/ 6457 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6458 { 6459 PetscErrorCode ierr; 6460 6461 PetscFunctionBegin; 6462 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6463 PetscValidType(mat,1); 6464 MatCheckPreallocated(mat,1); 6465 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6466 PetscFunctionReturn(0); 6467 } 6468 6469 /*@C 6470 MatGetOwnershipIS - Get row and column ownership as index sets 6471 6472 Not Collective 6473 6474 Input Arguments: 6475 . A - matrix of type Elemental 6476 6477 Output Arguments: 6478 + rows - rows in which this process owns elements 6479 - cols - columns in which this process owns elements 6480 6481 Level: intermediate 6482 6483 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL 6484 @*/ 6485 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6486 { 6487 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6488 6489 PetscFunctionBegin; 6490 MatCheckPreallocated(A,1); 6491 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6492 if (f) { 6493 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6494 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6495 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6496 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6497 } 6498 PetscFunctionReturn(0); 6499 } 6500 6501 /*@C 6502 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6503 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6504 to complete the factorization. 6505 6506 Collective on Mat 6507 6508 Input Parameters: 6509 + mat - the matrix 6510 . row - row permutation 6511 . column - column permutation 6512 - info - structure containing 6513 $ levels - number of levels of fill. 6514 $ expected fill - as ratio of original fill. 6515 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6516 missing diagonal entries) 6517 6518 Output Parameters: 6519 . fact - new matrix that has been symbolically factored 6520 6521 Notes: 6522 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6523 6524 Most users should employ the simplified KSP interface for linear solvers 6525 instead of working directly with matrix algebra routines such as this. 6526 See, e.g., KSPCreate(). 6527 6528 Level: developer 6529 6530 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6531 MatGetOrdering(), MatFactorInfo 6532 6533 Note: this uses the definition of level of fill as in Y. Saad, 2003 6534 6535 Developer Note: fortran interface is not autogenerated as the f90 6536 interface defintion cannot be generated correctly [due to MatFactorInfo] 6537 6538 References: 6539 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6540 @*/ 6541 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6542 { 6543 PetscErrorCode ierr; 6544 6545 PetscFunctionBegin; 6546 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6547 PetscValidType(mat,1); 6548 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6549 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6550 PetscValidPointer(info,4); 6551 PetscValidPointer(fact,5); 6552 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6553 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6554 if (!(fact)->ops->ilufactorsymbolic) { 6555 MatSolverType spackage; 6556 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6557 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6558 } 6559 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6560 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6561 MatCheckPreallocated(mat,2); 6562 6563 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6564 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6565 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6566 PetscFunctionReturn(0); 6567 } 6568 6569 /*@C 6570 MatICCFactorSymbolic - Performs symbolic incomplete 6571 Cholesky factorization for a symmetric matrix. Use 6572 MatCholeskyFactorNumeric() to complete the factorization. 6573 6574 Collective on Mat 6575 6576 Input Parameters: 6577 + mat - the matrix 6578 . perm - row and column permutation 6579 - info - structure containing 6580 $ levels - number of levels of fill. 6581 $ expected fill - as ratio of original fill. 6582 6583 Output Parameter: 6584 . fact - the factored matrix 6585 6586 Notes: 6587 Most users should employ the KSP interface for linear solvers 6588 instead of working directly with matrix algebra routines such as this. 6589 See, e.g., KSPCreate(). 6590 6591 Level: developer 6592 6593 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6594 6595 Note: this uses the definition of level of fill as in Y. Saad, 2003 6596 6597 Developer Note: fortran interface is not autogenerated as the f90 6598 interface defintion cannot be generated correctly [due to MatFactorInfo] 6599 6600 References: 6601 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6602 @*/ 6603 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6604 { 6605 PetscErrorCode ierr; 6606 6607 PetscFunctionBegin; 6608 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6609 PetscValidType(mat,1); 6610 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6611 PetscValidPointer(info,3); 6612 PetscValidPointer(fact,4); 6613 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6614 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6615 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6616 if (!(fact)->ops->iccfactorsymbolic) { 6617 MatSolverType spackage; 6618 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6619 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6620 } 6621 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6622 MatCheckPreallocated(mat,2); 6623 6624 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6625 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6626 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6627 PetscFunctionReturn(0); 6628 } 6629 6630 /*@C 6631 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6632 points to an array of valid matrices, they may be reused to store the new 6633 submatrices. 6634 6635 Collective on Mat 6636 6637 Input Parameters: 6638 + mat - the matrix 6639 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6640 . irow, icol - index sets of rows and columns to extract 6641 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6642 6643 Output Parameter: 6644 . submat - the array of submatrices 6645 6646 Notes: 6647 MatCreateSubMatrices() can extract ONLY sequential submatrices 6648 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6649 to extract a parallel submatrix. 6650 6651 Some matrix types place restrictions on the row and column 6652 indices, such as that they be sorted or that they be equal to each other. 6653 6654 The index sets may not have duplicate entries. 6655 6656 When extracting submatrices from a parallel matrix, each processor can 6657 form a different submatrix by setting the rows and columns of its 6658 individual index sets according to the local submatrix desired. 6659 6660 When finished using the submatrices, the user should destroy 6661 them with MatDestroySubMatrices(). 6662 6663 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6664 original matrix has not changed from that last call to MatCreateSubMatrices(). 6665 6666 This routine creates the matrices in submat; you should NOT create them before 6667 calling it. It also allocates the array of matrix pointers submat. 6668 6669 For BAIJ matrices the index sets must respect the block structure, that is if they 6670 request one row/column in a block, they must request all rows/columns that are in 6671 that block. For example, if the block size is 2 you cannot request just row 0 and 6672 column 0. 6673 6674 Fortran Note: 6675 The Fortran interface is slightly different from that given below; it 6676 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6677 6678 Level: advanced 6679 6680 6681 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6682 @*/ 6683 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6684 { 6685 PetscErrorCode ierr; 6686 PetscInt i; 6687 PetscBool eq; 6688 6689 PetscFunctionBegin; 6690 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6691 PetscValidType(mat,1); 6692 if (n) { 6693 PetscValidPointer(irow,3); 6694 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6695 PetscValidPointer(icol,4); 6696 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6697 } 6698 PetscValidPointer(submat,6); 6699 if (n && scall == MAT_REUSE_MATRIX) { 6700 PetscValidPointer(*submat,6); 6701 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6702 } 6703 if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6704 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6705 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6706 MatCheckPreallocated(mat,1); 6707 6708 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6709 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6710 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6711 for (i=0; i<n; i++) { 6712 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6713 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6714 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6715 if (eq) { 6716 if (mat->symmetric) { 6717 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6718 } else if (mat->hermitian) { 6719 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6720 } else if (mat->structurally_symmetric) { 6721 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6722 } 6723 } 6724 } 6725 } 6726 PetscFunctionReturn(0); 6727 } 6728 6729 /*@C 6730 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6731 6732 Collective on Mat 6733 6734 Input Parameters: 6735 + mat - the matrix 6736 . n - the number of submatrixes to be extracted 6737 . irow, icol - index sets of rows and columns to extract 6738 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6739 6740 Output Parameter: 6741 . submat - the array of submatrices 6742 6743 Level: advanced 6744 6745 6746 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6747 @*/ 6748 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6749 { 6750 PetscErrorCode ierr; 6751 PetscInt i; 6752 PetscBool eq; 6753 6754 PetscFunctionBegin; 6755 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6756 PetscValidType(mat,1); 6757 if (n) { 6758 PetscValidPointer(irow,3); 6759 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6760 PetscValidPointer(icol,4); 6761 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6762 } 6763 PetscValidPointer(submat,6); 6764 if (n && scall == MAT_REUSE_MATRIX) { 6765 PetscValidPointer(*submat,6); 6766 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6767 } 6768 if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6769 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6770 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6771 MatCheckPreallocated(mat,1); 6772 6773 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6774 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6775 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6776 for (i=0; i<n; i++) { 6777 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6778 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6779 if (eq) { 6780 if (mat->symmetric) { 6781 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6782 } else if (mat->hermitian) { 6783 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6784 } else if (mat->structurally_symmetric) { 6785 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6786 } 6787 } 6788 } 6789 } 6790 PetscFunctionReturn(0); 6791 } 6792 6793 /*@C 6794 MatDestroyMatrices - Destroys an array of matrices. 6795 6796 Collective on Mat 6797 6798 Input Parameters: 6799 + n - the number of local matrices 6800 - mat - the matrices (note that this is a pointer to the array of matrices) 6801 6802 Level: advanced 6803 6804 Notes: 6805 Frees not only the matrices, but also the array that contains the matrices 6806 In Fortran will not free the array. 6807 6808 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 6809 @*/ 6810 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6811 { 6812 PetscErrorCode ierr; 6813 PetscInt i; 6814 6815 PetscFunctionBegin; 6816 if (!*mat) PetscFunctionReturn(0); 6817 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6818 PetscValidPointer(mat,2); 6819 6820 for (i=0; i<n; i++) { 6821 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 6822 } 6823 6824 /* memory is allocated even if n = 0 */ 6825 ierr = PetscFree(*mat);CHKERRQ(ierr); 6826 PetscFunctionReturn(0); 6827 } 6828 6829 /*@C 6830 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 6831 6832 Collective on Mat 6833 6834 Input Parameters: 6835 + n - the number of local matrices 6836 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6837 sequence of MatCreateSubMatrices()) 6838 6839 Level: advanced 6840 6841 Notes: 6842 Frees not only the matrices, but also the array that contains the matrices 6843 In Fortran will not free the array. 6844 6845 .seealso: MatCreateSubMatrices() 6846 @*/ 6847 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 6848 { 6849 PetscErrorCode ierr; 6850 Mat mat0; 6851 6852 PetscFunctionBegin; 6853 if (!*mat) PetscFunctionReturn(0); 6854 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 6855 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6856 PetscValidPointer(mat,2); 6857 6858 mat0 = (*mat)[0]; 6859 if (mat0 && mat0->ops->destroysubmatrices) { 6860 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr); 6861 } else { 6862 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr); 6863 } 6864 PetscFunctionReturn(0); 6865 } 6866 6867 /*@C 6868 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 6869 6870 Collective on Mat 6871 6872 Input Parameters: 6873 . mat - the matrix 6874 6875 Output Parameter: 6876 . matstruct - the sequential matrix with the nonzero structure of mat 6877 6878 Level: intermediate 6879 6880 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 6881 @*/ 6882 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 6883 { 6884 PetscErrorCode ierr; 6885 6886 PetscFunctionBegin; 6887 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6888 PetscValidPointer(matstruct,2); 6889 6890 PetscValidType(mat,1); 6891 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6892 MatCheckPreallocated(mat,1); 6893 6894 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 6895 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6896 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 6897 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6898 PetscFunctionReturn(0); 6899 } 6900 6901 /*@C 6902 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 6903 6904 Collective on Mat 6905 6906 Input Parameters: 6907 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 6908 sequence of MatGetSequentialNonzeroStructure()) 6909 6910 Level: advanced 6911 6912 Notes: 6913 Frees not only the matrices, but also the array that contains the matrices 6914 6915 .seealso: MatGetSeqNonzeroStructure() 6916 @*/ 6917 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 6918 { 6919 PetscErrorCode ierr; 6920 6921 PetscFunctionBegin; 6922 PetscValidPointer(mat,1); 6923 ierr = MatDestroy(mat);CHKERRQ(ierr); 6924 PetscFunctionReturn(0); 6925 } 6926 6927 /*@ 6928 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 6929 replaces the index sets by larger ones that represent submatrices with 6930 additional overlap. 6931 6932 Collective on Mat 6933 6934 Input Parameters: 6935 + mat - the matrix 6936 . n - the number of index sets 6937 . is - the array of index sets (these index sets will changed during the call) 6938 - ov - the additional overlap requested 6939 6940 Options Database: 6941 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 6942 6943 Level: developer 6944 6945 6946 .seealso: MatCreateSubMatrices() 6947 @*/ 6948 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 6949 { 6950 PetscErrorCode ierr; 6951 6952 PetscFunctionBegin; 6953 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6954 PetscValidType(mat,1); 6955 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 6956 if (n) { 6957 PetscValidPointer(is,3); 6958 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 6959 } 6960 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6961 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6962 MatCheckPreallocated(mat,1); 6963 6964 if (!ov) PetscFunctionReturn(0); 6965 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6966 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6967 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 6968 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6969 PetscFunctionReturn(0); 6970 } 6971 6972 6973 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 6974 6975 /*@ 6976 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 6977 a sub communicator, replaces the index sets by larger ones that represent submatrices with 6978 additional overlap. 6979 6980 Collective on Mat 6981 6982 Input Parameters: 6983 + mat - the matrix 6984 . n - the number of index sets 6985 . is - the array of index sets (these index sets will changed during the call) 6986 - ov - the additional overlap requested 6987 6988 Options Database: 6989 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 6990 6991 Level: developer 6992 6993 6994 .seealso: MatCreateSubMatrices() 6995 @*/ 6996 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 6997 { 6998 PetscInt i; 6999 PetscErrorCode ierr; 7000 7001 PetscFunctionBegin; 7002 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7003 PetscValidType(mat,1); 7004 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7005 if (n) { 7006 PetscValidPointer(is,3); 7007 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7008 } 7009 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7010 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7011 MatCheckPreallocated(mat,1); 7012 if (!ov) PetscFunctionReturn(0); 7013 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7014 for(i=0; i<n; i++){ 7015 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 7016 } 7017 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7018 PetscFunctionReturn(0); 7019 } 7020 7021 7022 7023 7024 /*@ 7025 MatGetBlockSize - Returns the matrix block size. 7026 7027 Not Collective 7028 7029 Input Parameter: 7030 . mat - the matrix 7031 7032 Output Parameter: 7033 . bs - block size 7034 7035 Notes: 7036 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7037 7038 If the block size has not been set yet this routine returns 1. 7039 7040 Level: intermediate 7041 7042 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7043 @*/ 7044 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7045 { 7046 PetscFunctionBegin; 7047 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7048 PetscValidIntPointer(bs,2); 7049 *bs = PetscAbs(mat->rmap->bs); 7050 PetscFunctionReturn(0); 7051 } 7052 7053 /*@ 7054 MatGetBlockSizes - Returns the matrix block row and column sizes. 7055 7056 Not Collective 7057 7058 Input Parameter: 7059 . mat - the matrix 7060 7061 Output Parameter: 7062 + rbs - row block size 7063 - cbs - column block size 7064 7065 Notes: 7066 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7067 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7068 7069 If a block size has not been set yet this routine returns 1. 7070 7071 Level: intermediate 7072 7073 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7074 @*/ 7075 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7076 { 7077 PetscFunctionBegin; 7078 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7079 if (rbs) PetscValidIntPointer(rbs,2); 7080 if (cbs) PetscValidIntPointer(cbs,3); 7081 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7082 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7083 PetscFunctionReturn(0); 7084 } 7085 7086 /*@ 7087 MatSetBlockSize - Sets the matrix block size. 7088 7089 Logically Collective on Mat 7090 7091 Input Parameters: 7092 + mat - the matrix 7093 - bs - block size 7094 7095 Notes: 7096 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7097 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7098 7099 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7100 is compatible with the matrix local sizes. 7101 7102 Level: intermediate 7103 7104 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7105 @*/ 7106 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7107 { 7108 PetscErrorCode ierr; 7109 7110 PetscFunctionBegin; 7111 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7112 PetscValidLogicalCollectiveInt(mat,bs,2); 7113 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr); 7114 PetscFunctionReturn(0); 7115 } 7116 7117 /*@ 7118 MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size 7119 7120 Logically Collective on Mat 7121 7122 Input Parameters: 7123 + mat - the matrix 7124 . nblocks - the number of blocks on this process 7125 - bsizes - the block sizes 7126 7127 Notes: 7128 Currently used by PCVPBJACOBI for SeqAIJ matrices 7129 7130 Level: intermediate 7131 7132 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes() 7133 @*/ 7134 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7135 { 7136 PetscErrorCode ierr; 7137 PetscInt i,ncnt = 0, nlocal; 7138 7139 PetscFunctionBegin; 7140 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7141 if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7142 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr); 7143 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7144 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); 7145 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr); 7146 mat->nblocks = nblocks; 7147 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr); 7148 ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr); 7149 PetscFunctionReturn(0); 7150 } 7151 7152 /*@C 7153 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7154 7155 Logically Collective on Mat 7156 7157 Input Parameters: 7158 . mat - the matrix 7159 7160 Output Parameters: 7161 + nblocks - the number of blocks on this process 7162 - bsizes - the block sizes 7163 7164 Notes: Currently not supported from Fortran 7165 7166 Level: intermediate 7167 7168 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7169 @*/ 7170 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7171 { 7172 PetscFunctionBegin; 7173 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7174 *nblocks = mat->nblocks; 7175 *bsizes = mat->bsizes; 7176 PetscFunctionReturn(0); 7177 } 7178 7179 /*@ 7180 MatSetBlockSizes - Sets the matrix block row and column sizes. 7181 7182 Logically Collective on Mat 7183 7184 Input Parameters: 7185 + mat - the matrix 7186 . rbs - row block size 7187 - cbs - column block size 7188 7189 Notes: 7190 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7191 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7192 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7193 7194 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7195 are compatible with the matrix local sizes. 7196 7197 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7198 7199 Level: intermediate 7200 7201 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7202 @*/ 7203 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7204 { 7205 PetscErrorCode ierr; 7206 7207 PetscFunctionBegin; 7208 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7209 PetscValidLogicalCollectiveInt(mat,rbs,2); 7210 PetscValidLogicalCollectiveInt(mat,cbs,3); 7211 if (mat->ops->setblocksizes) { 7212 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr); 7213 } 7214 if (mat->rmap->refcnt) { 7215 ISLocalToGlobalMapping l2g = NULL; 7216 PetscLayout nmap = NULL; 7217 7218 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr); 7219 if (mat->rmap->mapping) { 7220 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr); 7221 } 7222 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr); 7223 mat->rmap = nmap; 7224 mat->rmap->mapping = l2g; 7225 } 7226 if (mat->cmap->refcnt) { 7227 ISLocalToGlobalMapping l2g = NULL; 7228 PetscLayout nmap = NULL; 7229 7230 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr); 7231 if (mat->cmap->mapping) { 7232 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr); 7233 } 7234 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 7235 mat->cmap = nmap; 7236 mat->cmap->mapping = l2g; 7237 } 7238 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7239 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7240 PetscFunctionReturn(0); 7241 } 7242 7243 /*@ 7244 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7245 7246 Logically Collective on Mat 7247 7248 Input Parameters: 7249 + mat - the matrix 7250 . fromRow - matrix from which to copy row block size 7251 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7252 7253 Level: developer 7254 7255 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7256 @*/ 7257 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7258 { 7259 PetscErrorCode ierr; 7260 7261 PetscFunctionBegin; 7262 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7263 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7264 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7265 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7266 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7267 PetscFunctionReturn(0); 7268 } 7269 7270 /*@ 7271 MatResidual - Default routine to calculate the residual. 7272 7273 Collective on Mat 7274 7275 Input Parameters: 7276 + mat - the matrix 7277 . b - the right-hand-side 7278 - x - the approximate solution 7279 7280 Output Parameter: 7281 . r - location to store the residual 7282 7283 Level: developer 7284 7285 .seealso: PCMGSetResidual() 7286 @*/ 7287 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7288 { 7289 PetscErrorCode ierr; 7290 7291 PetscFunctionBegin; 7292 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7293 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7294 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7295 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7296 PetscValidType(mat,1); 7297 MatCheckPreallocated(mat,1); 7298 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7299 if (!mat->ops->residual) { 7300 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7301 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7302 } else { 7303 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7304 } 7305 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7306 PetscFunctionReturn(0); 7307 } 7308 7309 /*@C 7310 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7311 7312 Collective on Mat 7313 7314 Input Parameters: 7315 + mat - the matrix 7316 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7317 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7318 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7319 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7320 always used. 7321 7322 Output Parameters: 7323 + n - number of rows in the (possibly compressed) matrix 7324 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7325 . ja - the column indices 7326 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7327 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7328 7329 Level: developer 7330 7331 Notes: 7332 You CANNOT change any of the ia[] or ja[] values. 7333 7334 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7335 7336 Fortran Notes: 7337 In Fortran use 7338 $ 7339 $ PetscInt ia(1), ja(1) 7340 $ PetscOffset iia, jja 7341 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7342 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7343 7344 or 7345 $ 7346 $ PetscInt, pointer :: ia(:),ja(:) 7347 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7348 $ ! Access the ith and jth entries via ia(i) and ja(j) 7349 7350 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7351 @*/ 7352 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7353 { 7354 PetscErrorCode ierr; 7355 7356 PetscFunctionBegin; 7357 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7358 PetscValidType(mat,1); 7359 PetscValidIntPointer(n,5); 7360 if (ia) PetscValidIntPointer(ia,6); 7361 if (ja) PetscValidIntPointer(ja,7); 7362 PetscValidIntPointer(done,8); 7363 MatCheckPreallocated(mat,1); 7364 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7365 else { 7366 *done = PETSC_TRUE; 7367 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7368 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7369 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7370 } 7371 PetscFunctionReturn(0); 7372 } 7373 7374 /*@C 7375 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7376 7377 Collective on Mat 7378 7379 Input Parameters: 7380 + mat - the matrix 7381 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7382 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7383 symmetrized 7384 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7385 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7386 always used. 7387 . n - number of columns in the (possibly compressed) matrix 7388 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7389 - ja - the row indices 7390 7391 Output Parameters: 7392 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7393 7394 Level: developer 7395 7396 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7397 @*/ 7398 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7399 { 7400 PetscErrorCode ierr; 7401 7402 PetscFunctionBegin; 7403 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7404 PetscValidType(mat,1); 7405 PetscValidIntPointer(n,4); 7406 if (ia) PetscValidIntPointer(ia,5); 7407 if (ja) PetscValidIntPointer(ja,6); 7408 PetscValidIntPointer(done,7); 7409 MatCheckPreallocated(mat,1); 7410 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7411 else { 7412 *done = PETSC_TRUE; 7413 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7414 } 7415 PetscFunctionReturn(0); 7416 } 7417 7418 /*@C 7419 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7420 MatGetRowIJ(). 7421 7422 Collective on Mat 7423 7424 Input Parameters: 7425 + mat - the matrix 7426 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7427 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7428 symmetrized 7429 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7430 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7431 always used. 7432 . n - size of (possibly compressed) matrix 7433 . ia - the row pointers 7434 - ja - the column indices 7435 7436 Output Parameters: 7437 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7438 7439 Note: 7440 This routine zeros out n, ia, and ja. This is to prevent accidental 7441 us of the array after it has been restored. If you pass NULL, it will 7442 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7443 7444 Level: developer 7445 7446 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7447 @*/ 7448 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7449 { 7450 PetscErrorCode ierr; 7451 7452 PetscFunctionBegin; 7453 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7454 PetscValidType(mat,1); 7455 if (ia) PetscValidIntPointer(ia,6); 7456 if (ja) PetscValidIntPointer(ja,7); 7457 PetscValidIntPointer(done,8); 7458 MatCheckPreallocated(mat,1); 7459 7460 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7461 else { 7462 *done = PETSC_TRUE; 7463 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7464 if (n) *n = 0; 7465 if (ia) *ia = NULL; 7466 if (ja) *ja = NULL; 7467 } 7468 PetscFunctionReturn(0); 7469 } 7470 7471 /*@C 7472 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7473 MatGetColumnIJ(). 7474 7475 Collective on Mat 7476 7477 Input Parameters: 7478 + mat - the matrix 7479 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7480 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7481 symmetrized 7482 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7483 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7484 always used. 7485 7486 Output Parameters: 7487 + n - size of (possibly compressed) matrix 7488 . ia - the column pointers 7489 . ja - the row indices 7490 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7491 7492 Level: developer 7493 7494 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7495 @*/ 7496 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7497 { 7498 PetscErrorCode ierr; 7499 7500 PetscFunctionBegin; 7501 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7502 PetscValidType(mat,1); 7503 if (ia) PetscValidIntPointer(ia,5); 7504 if (ja) PetscValidIntPointer(ja,6); 7505 PetscValidIntPointer(done,7); 7506 MatCheckPreallocated(mat,1); 7507 7508 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7509 else { 7510 *done = PETSC_TRUE; 7511 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7512 if (n) *n = 0; 7513 if (ia) *ia = NULL; 7514 if (ja) *ja = NULL; 7515 } 7516 PetscFunctionReturn(0); 7517 } 7518 7519 /*@C 7520 MatColoringPatch -Used inside matrix coloring routines that 7521 use MatGetRowIJ() and/or MatGetColumnIJ(). 7522 7523 Collective on Mat 7524 7525 Input Parameters: 7526 + mat - the matrix 7527 . ncolors - max color value 7528 . n - number of entries in colorarray 7529 - colorarray - array indicating color for each column 7530 7531 Output Parameters: 7532 . iscoloring - coloring generated using colorarray information 7533 7534 Level: developer 7535 7536 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7537 7538 @*/ 7539 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7540 { 7541 PetscErrorCode ierr; 7542 7543 PetscFunctionBegin; 7544 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7545 PetscValidType(mat,1); 7546 PetscValidIntPointer(colorarray,4); 7547 PetscValidPointer(iscoloring,5); 7548 MatCheckPreallocated(mat,1); 7549 7550 if (!mat->ops->coloringpatch) { 7551 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7552 } else { 7553 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7554 } 7555 PetscFunctionReturn(0); 7556 } 7557 7558 7559 /*@ 7560 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7561 7562 Logically Collective on Mat 7563 7564 Input Parameter: 7565 . mat - the factored matrix to be reset 7566 7567 Notes: 7568 This routine should be used only with factored matrices formed by in-place 7569 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7570 format). This option can save memory, for example, when solving nonlinear 7571 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7572 ILU(0) preconditioner. 7573 7574 Note that one can specify in-place ILU(0) factorization by calling 7575 .vb 7576 PCType(pc,PCILU); 7577 PCFactorSeUseInPlace(pc); 7578 .ve 7579 or by using the options -pc_type ilu -pc_factor_in_place 7580 7581 In-place factorization ILU(0) can also be used as a local 7582 solver for the blocks within the block Jacobi or additive Schwarz 7583 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7584 for details on setting local solver options. 7585 7586 Most users should employ the simplified KSP interface for linear solvers 7587 instead of working directly with matrix algebra routines such as this. 7588 See, e.g., KSPCreate(). 7589 7590 Level: developer 7591 7592 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7593 7594 @*/ 7595 PetscErrorCode MatSetUnfactored(Mat mat) 7596 { 7597 PetscErrorCode ierr; 7598 7599 PetscFunctionBegin; 7600 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7601 PetscValidType(mat,1); 7602 MatCheckPreallocated(mat,1); 7603 mat->factortype = MAT_FACTOR_NONE; 7604 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7605 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7606 PetscFunctionReturn(0); 7607 } 7608 7609 /*MC 7610 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7611 7612 Synopsis: 7613 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7614 7615 Not collective 7616 7617 Input Parameter: 7618 . x - matrix 7619 7620 Output Parameters: 7621 + xx_v - the Fortran90 pointer to the array 7622 - ierr - error code 7623 7624 Example of Usage: 7625 .vb 7626 PetscScalar, pointer xx_v(:,:) 7627 .... 7628 call MatDenseGetArrayF90(x,xx_v,ierr) 7629 a = xx_v(3) 7630 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7631 .ve 7632 7633 Level: advanced 7634 7635 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7636 7637 M*/ 7638 7639 /*MC 7640 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7641 accessed with MatDenseGetArrayF90(). 7642 7643 Synopsis: 7644 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7645 7646 Not collective 7647 7648 Input Parameters: 7649 + x - matrix 7650 - xx_v - the Fortran90 pointer to the array 7651 7652 Output Parameter: 7653 . ierr - error code 7654 7655 Example of Usage: 7656 .vb 7657 PetscScalar, pointer xx_v(:,:) 7658 .... 7659 call MatDenseGetArrayF90(x,xx_v,ierr) 7660 a = xx_v(3) 7661 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7662 .ve 7663 7664 Level: advanced 7665 7666 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7667 7668 M*/ 7669 7670 7671 /*MC 7672 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7673 7674 Synopsis: 7675 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7676 7677 Not collective 7678 7679 Input Parameter: 7680 . x - matrix 7681 7682 Output Parameters: 7683 + xx_v - the Fortran90 pointer to the array 7684 - ierr - error code 7685 7686 Example of Usage: 7687 .vb 7688 PetscScalar, pointer xx_v(:) 7689 .... 7690 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7691 a = xx_v(3) 7692 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7693 .ve 7694 7695 Level: advanced 7696 7697 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7698 7699 M*/ 7700 7701 /*MC 7702 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7703 accessed with MatSeqAIJGetArrayF90(). 7704 7705 Synopsis: 7706 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7707 7708 Not collective 7709 7710 Input Parameters: 7711 + x - matrix 7712 - xx_v - the Fortran90 pointer to the array 7713 7714 Output Parameter: 7715 . ierr - error code 7716 7717 Example of Usage: 7718 .vb 7719 PetscScalar, pointer xx_v(:) 7720 .... 7721 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7722 a = xx_v(3) 7723 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7724 .ve 7725 7726 Level: advanced 7727 7728 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7729 7730 M*/ 7731 7732 7733 /*@ 7734 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7735 as the original matrix. 7736 7737 Collective on Mat 7738 7739 Input Parameters: 7740 + mat - the original matrix 7741 . isrow - parallel IS containing the rows this processor should obtain 7742 . 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. 7743 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7744 7745 Output Parameter: 7746 . newmat - the new submatrix, of the same type as the old 7747 7748 Level: advanced 7749 7750 Notes: 7751 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7752 7753 Some matrix types place restrictions on the row and column indices, such 7754 as that they be sorted or that they be equal to each other. 7755 7756 The index sets may not have duplicate entries. 7757 7758 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7759 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 7760 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7761 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7762 you are finished using it. 7763 7764 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7765 the input matrix. 7766 7767 If iscol is NULL then all columns are obtained (not supported in Fortran). 7768 7769 Example usage: 7770 Consider the following 8x8 matrix with 34 non-zero values, that is 7771 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7772 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7773 as follows: 7774 7775 .vb 7776 1 2 0 | 0 3 0 | 0 4 7777 Proc0 0 5 6 | 7 0 0 | 8 0 7778 9 0 10 | 11 0 0 | 12 0 7779 ------------------------------------- 7780 13 0 14 | 15 16 17 | 0 0 7781 Proc1 0 18 0 | 19 20 21 | 0 0 7782 0 0 0 | 22 23 0 | 24 0 7783 ------------------------------------- 7784 Proc2 25 26 27 | 0 0 28 | 29 0 7785 30 0 0 | 31 32 33 | 0 34 7786 .ve 7787 7788 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7789 7790 .vb 7791 2 0 | 0 3 0 | 0 7792 Proc0 5 6 | 7 0 0 | 8 7793 ------------------------------- 7794 Proc1 18 0 | 19 20 21 | 0 7795 ------------------------------- 7796 Proc2 26 27 | 0 0 28 | 29 7797 0 0 | 31 32 33 | 0 7798 .ve 7799 7800 7801 .seealso: MatCreateSubMatrices(), MatCreateSubMatricesMPI(), MatCreateSubMatrixVirtual(), MatSubMatrixVirtualUpdate() 7802 @*/ 7803 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7804 { 7805 PetscErrorCode ierr; 7806 PetscMPIInt size; 7807 Mat *local; 7808 IS iscoltmp; 7809 7810 PetscFunctionBegin; 7811 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7812 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7813 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7814 PetscValidPointer(newmat,5); 7815 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7816 PetscValidType(mat,1); 7817 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7818 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 7819 7820 MatCheckPreallocated(mat,1); 7821 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 7822 7823 if (!iscol || isrow == iscol) { 7824 PetscBool stride; 7825 PetscMPIInt grabentirematrix = 0,grab; 7826 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 7827 if (stride) { 7828 PetscInt first,step,n,rstart,rend; 7829 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 7830 if (step == 1) { 7831 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 7832 if (rstart == first) { 7833 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 7834 if (n == rend-rstart) { 7835 grabentirematrix = 1; 7836 } 7837 } 7838 } 7839 } 7840 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 7841 if (grab) { 7842 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 7843 if (cll == MAT_INITIAL_MATRIX) { 7844 *newmat = mat; 7845 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 7846 } 7847 PetscFunctionReturn(0); 7848 } 7849 } 7850 7851 if (!iscol) { 7852 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 7853 } else { 7854 iscoltmp = iscol; 7855 } 7856 7857 /* if original matrix is on just one processor then use submatrix generated */ 7858 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 7859 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 7860 goto setproperties; 7861 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 7862 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 7863 *newmat = *local; 7864 ierr = PetscFree(local);CHKERRQ(ierr); 7865 goto setproperties; 7866 } else if (!mat->ops->createsubmatrix) { 7867 /* Create a new matrix type that implements the operation using the full matrix */ 7868 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7869 switch (cll) { 7870 case MAT_INITIAL_MATRIX: 7871 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 7872 break; 7873 case MAT_REUSE_MATRIX: 7874 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 7875 break; 7876 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 7877 } 7878 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7879 goto setproperties; 7880 } 7881 7882 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7883 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7884 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 7885 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7886 7887 /* Propagate symmetry information for diagonal blocks */ 7888 setproperties: 7889 if (isrow == iscoltmp) { 7890 if (mat->symmetric_set && mat->symmetric) { 7891 ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 7892 } 7893 if (mat->structurally_symmetric_set && mat->structurally_symmetric) { 7894 ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 7895 } 7896 if (mat->hermitian_set && mat->hermitian) { 7897 ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 7898 } 7899 if (mat->spd_set && mat->spd) { 7900 ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 7901 } 7902 } 7903 7904 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7905 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 7906 PetscFunctionReturn(0); 7907 } 7908 7909 /*@ 7910 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 7911 used during the assembly process to store values that belong to 7912 other processors. 7913 7914 Not Collective 7915 7916 Input Parameters: 7917 + mat - the matrix 7918 . size - the initial size of the stash. 7919 - bsize - the initial size of the block-stash(if used). 7920 7921 Options Database Keys: 7922 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 7923 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 7924 7925 Level: intermediate 7926 7927 Notes: 7928 The block-stash is used for values set with MatSetValuesBlocked() while 7929 the stash is used for values set with MatSetValues() 7930 7931 Run with the option -info and look for output of the form 7932 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 7933 to determine the appropriate value, MM, to use for size and 7934 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 7935 to determine the value, BMM to use for bsize 7936 7937 7938 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 7939 7940 @*/ 7941 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 7942 { 7943 PetscErrorCode ierr; 7944 7945 PetscFunctionBegin; 7946 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7947 PetscValidType(mat,1); 7948 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 7949 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 7950 PetscFunctionReturn(0); 7951 } 7952 7953 /*@ 7954 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 7955 the matrix 7956 7957 Neighbor-wise Collective on Mat 7958 7959 Input Parameters: 7960 + mat - the matrix 7961 . x,y - the vectors 7962 - w - where the result is stored 7963 7964 Level: intermediate 7965 7966 Notes: 7967 w may be the same vector as y. 7968 7969 This allows one to use either the restriction or interpolation (its transpose) 7970 matrix to do the interpolation 7971 7972 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 7973 7974 @*/ 7975 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 7976 { 7977 PetscErrorCode ierr; 7978 PetscInt M,N,Ny; 7979 7980 PetscFunctionBegin; 7981 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7982 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7983 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 7984 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 7985 PetscValidType(A,1); 7986 MatCheckPreallocated(A,1); 7987 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 7988 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 7989 if (M == Ny) { 7990 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 7991 } else { 7992 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 7993 } 7994 PetscFunctionReturn(0); 7995 } 7996 7997 /*@ 7998 MatInterpolate - y = A*x or A'*x depending on the shape of 7999 the matrix 8000 8001 Neighbor-wise Collective on Mat 8002 8003 Input Parameters: 8004 + mat - the matrix 8005 - x,y - the vectors 8006 8007 Level: intermediate 8008 8009 Notes: 8010 This allows one to use either the restriction or interpolation (its transpose) 8011 matrix to do the interpolation 8012 8013 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8014 8015 @*/ 8016 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8017 { 8018 PetscErrorCode ierr; 8019 PetscInt M,N,Ny; 8020 8021 PetscFunctionBegin; 8022 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8023 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8024 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8025 PetscValidType(A,1); 8026 MatCheckPreallocated(A,1); 8027 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8028 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8029 if (M == Ny) { 8030 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8031 } else { 8032 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8033 } 8034 PetscFunctionReturn(0); 8035 } 8036 8037 /*@ 8038 MatRestrict - y = A*x or A'*x 8039 8040 Neighbor-wise Collective on Mat 8041 8042 Input Parameters: 8043 + mat - the matrix 8044 - x,y - the vectors 8045 8046 Level: intermediate 8047 8048 Notes: 8049 This allows one to use either the restriction or interpolation (its transpose) 8050 matrix to do the restriction 8051 8052 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8053 8054 @*/ 8055 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8056 { 8057 PetscErrorCode ierr; 8058 PetscInt M,N,Ny; 8059 8060 PetscFunctionBegin; 8061 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8062 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8063 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8064 PetscValidType(A,1); 8065 MatCheckPreallocated(A,1); 8066 8067 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8068 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8069 if (M == Ny) { 8070 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8071 } else { 8072 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8073 } 8074 PetscFunctionReturn(0); 8075 } 8076 8077 /*@ 8078 MatGetNullSpace - retrieves the null space of a matrix. 8079 8080 Logically Collective on Mat 8081 8082 Input Parameters: 8083 + mat - the matrix 8084 - nullsp - the null space object 8085 8086 Level: developer 8087 8088 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8089 @*/ 8090 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8091 { 8092 PetscFunctionBegin; 8093 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8094 PetscValidPointer(nullsp,2); 8095 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8096 PetscFunctionReturn(0); 8097 } 8098 8099 /*@ 8100 MatSetNullSpace - attaches a null space to a matrix. 8101 8102 Logically Collective on Mat 8103 8104 Input Parameters: 8105 + mat - the matrix 8106 - nullsp - the null space object 8107 8108 Level: advanced 8109 8110 Notes: 8111 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8112 8113 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8114 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8115 8116 You can remove the null space by calling this routine with an nullsp of NULL 8117 8118 8119 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8120 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). 8121 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 8122 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 8123 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). 8124 8125 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8126 8127 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 8128 routine also automatically calls MatSetTransposeNullSpace(). 8129 8130 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8131 @*/ 8132 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8133 { 8134 PetscErrorCode ierr; 8135 8136 PetscFunctionBegin; 8137 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8138 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8139 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8140 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8141 mat->nullsp = nullsp; 8142 if (mat->symmetric_set && mat->symmetric) { 8143 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8144 } 8145 PetscFunctionReturn(0); 8146 } 8147 8148 /*@ 8149 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8150 8151 Logically Collective on Mat 8152 8153 Input Parameters: 8154 + mat - the matrix 8155 - nullsp - the null space object 8156 8157 Level: developer 8158 8159 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8160 @*/ 8161 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8162 { 8163 PetscFunctionBegin; 8164 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8165 PetscValidType(mat,1); 8166 PetscValidPointer(nullsp,2); 8167 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8168 PetscFunctionReturn(0); 8169 } 8170 8171 /*@ 8172 MatSetTransposeNullSpace - attaches a null space to a matrix. 8173 8174 Logically Collective on Mat 8175 8176 Input Parameters: 8177 + mat - the matrix 8178 - nullsp - the null space object 8179 8180 Level: advanced 8181 8182 Notes: 8183 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. 8184 You must also call MatSetNullSpace() 8185 8186 8187 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8188 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). 8189 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 8190 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 8191 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). 8192 8193 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8194 8195 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8196 @*/ 8197 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8198 { 8199 PetscErrorCode ierr; 8200 8201 PetscFunctionBegin; 8202 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8203 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8204 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8205 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8206 mat->transnullsp = nullsp; 8207 PetscFunctionReturn(0); 8208 } 8209 8210 /*@ 8211 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8212 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8213 8214 Logically Collective on Mat 8215 8216 Input Parameters: 8217 + mat - the matrix 8218 - nullsp - the null space object 8219 8220 Level: advanced 8221 8222 Notes: 8223 Overwrites any previous near null space that may have been attached 8224 8225 You can remove the null space by calling this routine with an nullsp of NULL 8226 8227 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8228 @*/ 8229 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8230 { 8231 PetscErrorCode ierr; 8232 8233 PetscFunctionBegin; 8234 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8235 PetscValidType(mat,1); 8236 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8237 MatCheckPreallocated(mat,1); 8238 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8239 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8240 mat->nearnullsp = nullsp; 8241 PetscFunctionReturn(0); 8242 } 8243 8244 /*@ 8245 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8246 8247 Not Collective 8248 8249 Input Parameters: 8250 . mat - the matrix 8251 8252 Output Parameters: 8253 . nullsp - the null space object, NULL if not set 8254 8255 Level: developer 8256 8257 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8258 @*/ 8259 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8260 { 8261 PetscFunctionBegin; 8262 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8263 PetscValidType(mat,1); 8264 PetscValidPointer(nullsp,2); 8265 MatCheckPreallocated(mat,1); 8266 *nullsp = mat->nearnullsp; 8267 PetscFunctionReturn(0); 8268 } 8269 8270 /*@C 8271 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8272 8273 Collective on Mat 8274 8275 Input Parameters: 8276 + mat - the matrix 8277 . row - row/column permutation 8278 . fill - expected fill factor >= 1.0 8279 - level - level of fill, for ICC(k) 8280 8281 Notes: 8282 Probably really in-place only when level of fill is zero, otherwise allocates 8283 new space to store factored matrix and deletes previous memory. 8284 8285 Most users should employ the simplified KSP interface for linear solvers 8286 instead of working directly with matrix algebra routines such as this. 8287 See, e.g., KSPCreate(). 8288 8289 Level: developer 8290 8291 8292 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8293 8294 Developer Note: fortran interface is not autogenerated as the f90 8295 interface defintion cannot be generated correctly [due to MatFactorInfo] 8296 8297 @*/ 8298 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8299 { 8300 PetscErrorCode ierr; 8301 8302 PetscFunctionBegin; 8303 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8304 PetscValidType(mat,1); 8305 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8306 PetscValidPointer(info,3); 8307 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8308 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8309 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8310 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8311 MatCheckPreallocated(mat,1); 8312 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8313 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8314 PetscFunctionReturn(0); 8315 } 8316 8317 /*@ 8318 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8319 ghosted ones. 8320 8321 Not Collective 8322 8323 Input Parameters: 8324 + mat - the matrix 8325 - diag = the diagonal values, including ghost ones 8326 8327 Level: developer 8328 8329 Notes: 8330 Works only for MPIAIJ and MPIBAIJ matrices 8331 8332 .seealso: MatDiagonalScale() 8333 @*/ 8334 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8335 { 8336 PetscErrorCode ierr; 8337 PetscMPIInt size; 8338 8339 PetscFunctionBegin; 8340 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8341 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8342 PetscValidType(mat,1); 8343 8344 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8345 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8346 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8347 if (size == 1) { 8348 PetscInt n,m; 8349 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8350 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8351 if (m == n) { 8352 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8353 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8354 } else { 8355 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8356 } 8357 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8358 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8359 PetscFunctionReturn(0); 8360 } 8361 8362 /*@ 8363 MatGetInertia - Gets the inertia from a factored matrix 8364 8365 Collective on Mat 8366 8367 Input Parameter: 8368 . mat - the matrix 8369 8370 Output Parameters: 8371 + nneg - number of negative eigenvalues 8372 . nzero - number of zero eigenvalues 8373 - npos - number of positive eigenvalues 8374 8375 Level: advanced 8376 8377 Notes: 8378 Matrix must have been factored by MatCholeskyFactor() 8379 8380 8381 @*/ 8382 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8383 { 8384 PetscErrorCode ierr; 8385 8386 PetscFunctionBegin; 8387 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8388 PetscValidType(mat,1); 8389 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8390 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8391 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8392 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8393 PetscFunctionReturn(0); 8394 } 8395 8396 /* ----------------------------------------------------------------*/ 8397 /*@C 8398 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8399 8400 Neighbor-wise Collective on Mats 8401 8402 Input Parameters: 8403 + mat - the factored matrix 8404 - b - the right-hand-side vectors 8405 8406 Output Parameter: 8407 . x - the result vectors 8408 8409 Notes: 8410 The vectors b and x cannot be the same. I.e., one cannot 8411 call MatSolves(A,x,x). 8412 8413 Notes: 8414 Most users should employ the simplified KSP interface for linear solvers 8415 instead of working directly with matrix algebra routines such as this. 8416 See, e.g., KSPCreate(). 8417 8418 Level: developer 8419 8420 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8421 @*/ 8422 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8423 { 8424 PetscErrorCode ierr; 8425 8426 PetscFunctionBegin; 8427 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8428 PetscValidType(mat,1); 8429 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8430 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8431 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8432 8433 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8434 MatCheckPreallocated(mat,1); 8435 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8436 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8437 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8438 PetscFunctionReturn(0); 8439 } 8440 8441 /*@ 8442 MatIsSymmetric - Test whether a matrix is symmetric 8443 8444 Collective on Mat 8445 8446 Input Parameter: 8447 + A - the matrix to test 8448 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8449 8450 Output Parameters: 8451 . flg - the result 8452 8453 Notes: 8454 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8455 8456 Level: intermediate 8457 8458 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8459 @*/ 8460 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8461 { 8462 PetscErrorCode ierr; 8463 8464 PetscFunctionBegin; 8465 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8466 PetscValidBoolPointer(flg,2); 8467 8468 if (!A->symmetric_set) { 8469 if (!A->ops->issymmetric) { 8470 MatType mattype; 8471 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8472 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8473 } 8474 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8475 if (!tol) { 8476 A->symmetric_set = PETSC_TRUE; 8477 A->symmetric = *flg; 8478 if (A->symmetric) { 8479 A->structurally_symmetric_set = PETSC_TRUE; 8480 A->structurally_symmetric = PETSC_TRUE; 8481 } 8482 } 8483 } else if (A->symmetric) { 8484 *flg = PETSC_TRUE; 8485 } else if (!tol) { 8486 *flg = PETSC_FALSE; 8487 } else { 8488 if (!A->ops->issymmetric) { 8489 MatType mattype; 8490 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8491 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8492 } 8493 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8494 } 8495 PetscFunctionReturn(0); 8496 } 8497 8498 /*@ 8499 MatIsHermitian - Test whether a matrix is Hermitian 8500 8501 Collective on Mat 8502 8503 Input Parameter: 8504 + A - the matrix to test 8505 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8506 8507 Output Parameters: 8508 . flg - the result 8509 8510 Level: intermediate 8511 8512 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8513 MatIsSymmetricKnown(), MatIsSymmetric() 8514 @*/ 8515 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8516 { 8517 PetscErrorCode ierr; 8518 8519 PetscFunctionBegin; 8520 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8521 PetscValidBoolPointer(flg,2); 8522 8523 if (!A->hermitian_set) { 8524 if (!A->ops->ishermitian) { 8525 MatType mattype; 8526 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8527 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8528 } 8529 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8530 if (!tol) { 8531 A->hermitian_set = PETSC_TRUE; 8532 A->hermitian = *flg; 8533 if (A->hermitian) { 8534 A->structurally_symmetric_set = PETSC_TRUE; 8535 A->structurally_symmetric = PETSC_TRUE; 8536 } 8537 } 8538 } else if (A->hermitian) { 8539 *flg = PETSC_TRUE; 8540 } else if (!tol) { 8541 *flg = PETSC_FALSE; 8542 } else { 8543 if (!A->ops->ishermitian) { 8544 MatType mattype; 8545 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8546 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8547 } 8548 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8549 } 8550 PetscFunctionReturn(0); 8551 } 8552 8553 /*@ 8554 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8555 8556 Not Collective 8557 8558 Input Parameter: 8559 . A - the matrix to check 8560 8561 Output Parameters: 8562 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8563 - flg - the result 8564 8565 Level: advanced 8566 8567 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8568 if you want it explicitly checked 8569 8570 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8571 @*/ 8572 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8573 { 8574 PetscFunctionBegin; 8575 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8576 PetscValidPointer(set,2); 8577 PetscValidBoolPointer(flg,3); 8578 if (A->symmetric_set) { 8579 *set = PETSC_TRUE; 8580 *flg = A->symmetric; 8581 } else { 8582 *set = PETSC_FALSE; 8583 } 8584 PetscFunctionReturn(0); 8585 } 8586 8587 /*@ 8588 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8589 8590 Not Collective 8591 8592 Input Parameter: 8593 . A - the matrix to check 8594 8595 Output Parameters: 8596 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8597 - flg - the result 8598 8599 Level: advanced 8600 8601 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8602 if you want it explicitly checked 8603 8604 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8605 @*/ 8606 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8607 { 8608 PetscFunctionBegin; 8609 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8610 PetscValidPointer(set,2); 8611 PetscValidBoolPointer(flg,3); 8612 if (A->hermitian_set) { 8613 *set = PETSC_TRUE; 8614 *flg = A->hermitian; 8615 } else { 8616 *set = PETSC_FALSE; 8617 } 8618 PetscFunctionReturn(0); 8619 } 8620 8621 /*@ 8622 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8623 8624 Collective on Mat 8625 8626 Input Parameter: 8627 . A - the matrix to test 8628 8629 Output Parameters: 8630 . flg - the result 8631 8632 Level: intermediate 8633 8634 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8635 @*/ 8636 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8637 { 8638 PetscErrorCode ierr; 8639 8640 PetscFunctionBegin; 8641 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8642 PetscValidBoolPointer(flg,2); 8643 if (!A->structurally_symmetric_set) { 8644 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8645 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8646 8647 A->structurally_symmetric_set = PETSC_TRUE; 8648 } 8649 *flg = A->structurally_symmetric; 8650 PetscFunctionReturn(0); 8651 } 8652 8653 /*@ 8654 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8655 to be communicated to other processors during the MatAssemblyBegin/End() process 8656 8657 Not collective 8658 8659 Input Parameter: 8660 . vec - the vector 8661 8662 Output Parameters: 8663 + nstash - the size of the stash 8664 . reallocs - the number of additional mallocs incurred. 8665 . bnstash - the size of the block stash 8666 - breallocs - the number of additional mallocs incurred.in the block stash 8667 8668 Level: advanced 8669 8670 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8671 8672 @*/ 8673 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8674 { 8675 PetscErrorCode ierr; 8676 8677 PetscFunctionBegin; 8678 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8679 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8680 PetscFunctionReturn(0); 8681 } 8682 8683 /*@C 8684 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8685 parallel layout 8686 8687 Collective on Mat 8688 8689 Input Parameter: 8690 . mat - the matrix 8691 8692 Output Parameter: 8693 + right - (optional) vector that the matrix can be multiplied against 8694 - left - (optional) vector that the matrix vector product can be stored in 8695 8696 Notes: 8697 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(). 8698 8699 Notes: 8700 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8701 8702 Level: advanced 8703 8704 .seealso: MatCreate(), VecDestroy() 8705 @*/ 8706 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8707 { 8708 PetscErrorCode ierr; 8709 8710 PetscFunctionBegin; 8711 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8712 PetscValidType(mat,1); 8713 if (mat->ops->getvecs) { 8714 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8715 } else { 8716 PetscInt rbs,cbs; 8717 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8718 if (right) { 8719 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8720 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8721 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8722 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8723 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 8724 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8725 } 8726 if (left) { 8727 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8728 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8729 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8730 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8731 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 8732 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8733 } 8734 } 8735 PetscFunctionReturn(0); 8736 } 8737 8738 /*@C 8739 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8740 with default values. 8741 8742 Not Collective 8743 8744 Input Parameters: 8745 . info - the MatFactorInfo data structure 8746 8747 8748 Notes: 8749 The solvers are generally used through the KSP and PC objects, for example 8750 PCLU, PCILU, PCCHOLESKY, PCICC 8751 8752 Level: developer 8753 8754 .seealso: MatFactorInfo 8755 8756 Developer Note: fortran interface is not autogenerated as the f90 8757 interface defintion cannot be generated correctly [due to MatFactorInfo] 8758 8759 @*/ 8760 8761 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8762 { 8763 PetscErrorCode ierr; 8764 8765 PetscFunctionBegin; 8766 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8767 PetscFunctionReturn(0); 8768 } 8769 8770 /*@ 8771 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 8772 8773 Collective on Mat 8774 8775 Input Parameters: 8776 + mat - the factored matrix 8777 - is - the index set defining the Schur indices (0-based) 8778 8779 Notes: 8780 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 8781 8782 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 8783 8784 Level: developer 8785 8786 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 8787 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 8788 8789 @*/ 8790 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 8791 { 8792 PetscErrorCode ierr,(*f)(Mat,IS); 8793 8794 PetscFunctionBegin; 8795 PetscValidType(mat,1); 8796 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8797 PetscValidType(is,2); 8798 PetscValidHeaderSpecific(is,IS_CLASSID,2); 8799 PetscCheckSameComm(mat,1,is,2); 8800 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 8801 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 8802 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"); 8803 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 8804 ierr = (*f)(mat,is);CHKERRQ(ierr); 8805 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 8806 PetscFunctionReturn(0); 8807 } 8808 8809 /*@ 8810 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 8811 8812 Logically Collective on Mat 8813 8814 Input Parameters: 8815 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 8816 . S - location where to return the Schur complement, can be NULL 8817 - status - the status of the Schur complement matrix, can be NULL 8818 8819 Notes: 8820 You must call MatFactorSetSchurIS() before calling this routine. 8821 8822 The routine provides a copy of the Schur matrix stored within the solver data structures. 8823 The caller must destroy the object when it is no longer needed. 8824 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 8825 8826 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) 8827 8828 Developer Notes: 8829 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 8830 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 8831 8832 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 8833 8834 Level: advanced 8835 8836 References: 8837 8838 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 8839 @*/ 8840 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 8841 { 8842 PetscErrorCode ierr; 8843 8844 PetscFunctionBegin; 8845 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8846 if (S) PetscValidPointer(S,2); 8847 if (status) PetscValidPointer(status,3); 8848 if (S) { 8849 PetscErrorCode (*f)(Mat,Mat*); 8850 8851 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 8852 if (f) { 8853 ierr = (*f)(F,S);CHKERRQ(ierr); 8854 } else { 8855 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 8856 } 8857 } 8858 if (status) *status = F->schur_status; 8859 PetscFunctionReturn(0); 8860 } 8861 8862 /*@ 8863 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 8864 8865 Logically Collective on Mat 8866 8867 Input Parameters: 8868 + F - the factored matrix obtained by calling MatGetFactor() 8869 . *S - location where to return the Schur complement, can be NULL 8870 - status - the status of the Schur complement matrix, can be NULL 8871 8872 Notes: 8873 You must call MatFactorSetSchurIS() before calling this routine. 8874 8875 Schur complement mode is currently implemented for sequential matrices. 8876 The routine returns a the Schur Complement stored within the data strutures of the solver. 8877 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 8878 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 8879 8880 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 8881 8882 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 8883 8884 Level: advanced 8885 8886 References: 8887 8888 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 8889 @*/ 8890 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 8891 { 8892 PetscFunctionBegin; 8893 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8894 if (S) PetscValidPointer(S,2); 8895 if (status) PetscValidPointer(status,3); 8896 if (S) *S = F->schur; 8897 if (status) *status = F->schur_status; 8898 PetscFunctionReturn(0); 8899 } 8900 8901 /*@ 8902 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 8903 8904 Logically Collective on Mat 8905 8906 Input Parameters: 8907 + F - the factored matrix obtained by calling MatGetFactor() 8908 . *S - location where the Schur complement is stored 8909 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 8910 8911 Notes: 8912 8913 Level: advanced 8914 8915 References: 8916 8917 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 8918 @*/ 8919 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 8920 { 8921 PetscErrorCode ierr; 8922 8923 PetscFunctionBegin; 8924 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8925 if (S) { 8926 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 8927 *S = NULL; 8928 } 8929 F->schur_status = status; 8930 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 8931 PetscFunctionReturn(0); 8932 } 8933 8934 /*@ 8935 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 8936 8937 Logically Collective on Mat 8938 8939 Input Parameters: 8940 + F - the factored matrix obtained by calling MatGetFactor() 8941 . rhs - location where the right hand side of the Schur complement system is stored 8942 - sol - location where the solution of the Schur complement system has to be returned 8943 8944 Notes: 8945 The sizes of the vectors should match the size of the Schur complement 8946 8947 Must be called after MatFactorSetSchurIS() 8948 8949 Level: advanced 8950 8951 References: 8952 8953 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 8954 @*/ 8955 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 8956 { 8957 PetscErrorCode ierr; 8958 8959 PetscFunctionBegin; 8960 PetscValidType(F,1); 8961 PetscValidType(rhs,2); 8962 PetscValidType(sol,3); 8963 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8964 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 8965 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 8966 PetscCheckSameComm(F,1,rhs,2); 8967 PetscCheckSameComm(F,1,sol,3); 8968 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 8969 switch (F->schur_status) { 8970 case MAT_FACTOR_SCHUR_FACTORED: 8971 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 8972 break; 8973 case MAT_FACTOR_SCHUR_INVERTED: 8974 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 8975 break; 8976 default: 8977 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 8978 break; 8979 } 8980 PetscFunctionReturn(0); 8981 } 8982 8983 /*@ 8984 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 8985 8986 Logically Collective on Mat 8987 8988 Input Parameters: 8989 + F - the factored matrix obtained by calling MatGetFactor() 8990 . rhs - location where the right hand side of the Schur complement system is stored 8991 - sol - location where the solution of the Schur complement system has to be returned 8992 8993 Notes: 8994 The sizes of the vectors should match the size of the Schur complement 8995 8996 Must be called after MatFactorSetSchurIS() 8997 8998 Level: advanced 8999 9000 References: 9001 9002 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 9003 @*/ 9004 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9005 { 9006 PetscErrorCode ierr; 9007 9008 PetscFunctionBegin; 9009 PetscValidType(F,1); 9010 PetscValidType(rhs,2); 9011 PetscValidType(sol,3); 9012 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9013 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9014 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9015 PetscCheckSameComm(F,1,rhs,2); 9016 PetscCheckSameComm(F,1,sol,3); 9017 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9018 switch (F->schur_status) { 9019 case MAT_FACTOR_SCHUR_FACTORED: 9020 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 9021 break; 9022 case MAT_FACTOR_SCHUR_INVERTED: 9023 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 9024 break; 9025 default: 9026 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9027 break; 9028 } 9029 PetscFunctionReturn(0); 9030 } 9031 9032 /*@ 9033 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9034 9035 Logically Collective on Mat 9036 9037 Input Parameters: 9038 . F - the factored matrix obtained by calling MatGetFactor() 9039 9040 Notes: 9041 Must be called after MatFactorSetSchurIS(). 9042 9043 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9044 9045 Level: advanced 9046 9047 References: 9048 9049 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9050 @*/ 9051 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9052 { 9053 PetscErrorCode ierr; 9054 9055 PetscFunctionBegin; 9056 PetscValidType(F,1); 9057 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9058 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9059 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9060 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9061 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9062 PetscFunctionReturn(0); 9063 } 9064 9065 /*@ 9066 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9067 9068 Logically Collective on Mat 9069 9070 Input Parameters: 9071 . F - the factored matrix obtained by calling MatGetFactor() 9072 9073 Notes: 9074 Must be called after MatFactorSetSchurIS(). 9075 9076 Level: advanced 9077 9078 References: 9079 9080 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9081 @*/ 9082 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9083 { 9084 PetscErrorCode ierr; 9085 9086 PetscFunctionBegin; 9087 PetscValidType(F,1); 9088 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9089 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9090 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9091 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9092 PetscFunctionReturn(0); 9093 } 9094 9095 PetscErrorCode MatPtAP_Basic(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9096 { 9097 Mat AP; 9098 PetscErrorCode ierr; 9099 9100 PetscFunctionBegin; 9101 ierr = PetscInfo2(A,"Mat types %s and %s using basic PtAP\n",((PetscObject)A)->type_name,((PetscObject)P)->type_name);CHKERRQ(ierr); 9102 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AP);CHKERRQ(ierr); 9103 ierr = MatTransposeMatMult(P,AP,scall,fill,C);CHKERRQ(ierr); 9104 ierr = MatDestroy(&AP);CHKERRQ(ierr); 9105 PetscFunctionReturn(0); 9106 } 9107 9108 /*@ 9109 MatPtAP - Creates the matrix product C = P^T * A * P 9110 9111 Neighbor-wise Collective on Mat 9112 9113 Input Parameters: 9114 + A - the matrix 9115 . P - the projection matrix 9116 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9117 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9118 if the result is a dense matrix this is irrelevent 9119 9120 Output Parameters: 9121 . C - the product matrix 9122 9123 Notes: 9124 C will be created and must be destroyed by the user with MatDestroy(). 9125 9126 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9127 9128 Level: intermediate 9129 9130 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9131 @*/ 9132 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9133 { 9134 PetscErrorCode ierr; 9135 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9136 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9137 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9138 PetscBool sametype; 9139 9140 PetscFunctionBegin; 9141 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9142 PetscValidType(A,1); 9143 MatCheckPreallocated(A,1); 9144 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9145 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9146 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9147 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9148 PetscValidType(P,2); 9149 MatCheckPreallocated(P,2); 9150 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9151 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9152 9153 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); 9154 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); 9155 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9156 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9157 9158 if (scall == MAT_REUSE_MATRIX) { 9159 PetscValidPointer(*C,5); 9160 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9161 9162 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9163 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9164 if ((*C)->ops->ptapnumeric) { 9165 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9166 } else { 9167 ierr = MatPtAP_Basic(A,P,scall,fill,C); 9168 } 9169 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9170 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9171 PetscFunctionReturn(0); 9172 } 9173 9174 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9175 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9176 9177 fA = A->ops->ptap; 9178 fP = P->ops->ptap; 9179 ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr); 9180 if (fP == fA && sametype) { 9181 ptap = fA; 9182 } else { 9183 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9184 char ptapname[256]; 9185 ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr); 9186 ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9187 ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr); 9188 ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9189 ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9190 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9191 } 9192 9193 if (!ptap) ptap = MatPtAP_Basic; 9194 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9195 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9196 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9197 if (A->symmetric_set && A->symmetric) { 9198 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9199 } 9200 PetscFunctionReturn(0); 9201 } 9202 9203 /*@ 9204 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9205 9206 Neighbor-wise Collective on Mat 9207 9208 Input Parameters: 9209 + A - the matrix 9210 - P - the projection matrix 9211 9212 Output Parameters: 9213 . C - the product matrix 9214 9215 Notes: 9216 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9217 the user using MatDeatroy(). 9218 9219 This routine is currently only implemented for pairs of AIJ matrices and classes 9220 which inherit from AIJ. C will be of type MATAIJ. 9221 9222 Level: intermediate 9223 9224 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9225 @*/ 9226 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9227 { 9228 PetscErrorCode ierr; 9229 9230 PetscFunctionBegin; 9231 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9232 PetscValidType(A,1); 9233 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9234 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9235 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9236 PetscValidType(P,2); 9237 MatCheckPreallocated(P,2); 9238 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9239 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9240 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9241 PetscValidType(C,3); 9242 MatCheckPreallocated(C,3); 9243 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9244 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); 9245 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); 9246 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); 9247 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); 9248 MatCheckPreallocated(A,1); 9249 9250 if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first"); 9251 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9252 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9253 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9254 PetscFunctionReturn(0); 9255 } 9256 9257 /*@ 9258 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9259 9260 Neighbor-wise Collective on Mat 9261 9262 Input Parameters: 9263 + A - the matrix 9264 - P - the projection matrix 9265 9266 Output Parameters: 9267 . C - the (i,j) structure of the product matrix 9268 9269 Notes: 9270 C will be created and must be destroyed by the user with MatDestroy(). 9271 9272 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9273 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9274 this (i,j) structure by calling MatPtAPNumeric(). 9275 9276 Level: intermediate 9277 9278 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9279 @*/ 9280 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9281 { 9282 PetscErrorCode ierr; 9283 9284 PetscFunctionBegin; 9285 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9286 PetscValidType(A,1); 9287 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9288 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9289 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9290 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9291 PetscValidType(P,2); 9292 MatCheckPreallocated(P,2); 9293 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9294 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9295 PetscValidPointer(C,3); 9296 9297 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); 9298 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); 9299 MatCheckPreallocated(A,1); 9300 9301 if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name); 9302 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9303 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9304 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9305 9306 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9307 PetscFunctionReturn(0); 9308 } 9309 9310 /*@ 9311 MatRARt - Creates the matrix product C = R * A * R^T 9312 9313 Neighbor-wise Collective on Mat 9314 9315 Input Parameters: 9316 + A - the matrix 9317 . R - the projection matrix 9318 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9319 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9320 if the result is a dense matrix this is irrelevent 9321 9322 Output Parameters: 9323 . C - the product matrix 9324 9325 Notes: 9326 C will be created and must be destroyed by the user with MatDestroy(). 9327 9328 This routine is currently only implemented for pairs of AIJ matrices and classes 9329 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9330 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9331 We recommend using MatPtAP(). 9332 9333 Level: intermediate 9334 9335 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9336 @*/ 9337 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9338 { 9339 PetscErrorCode ierr; 9340 9341 PetscFunctionBegin; 9342 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9343 PetscValidType(A,1); 9344 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9345 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9346 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9347 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9348 PetscValidType(R,2); 9349 MatCheckPreallocated(R,2); 9350 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9351 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9352 PetscValidPointer(C,3); 9353 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); 9354 9355 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9356 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9357 MatCheckPreallocated(A,1); 9358 9359 if (!A->ops->rart) { 9360 Mat Rt; 9361 ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 9362 ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr); 9363 ierr = MatDestroy(&Rt);CHKERRQ(ierr); 9364 PetscFunctionReturn(0); 9365 } 9366 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9367 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9368 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9369 PetscFunctionReturn(0); 9370 } 9371 9372 /*@ 9373 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9374 9375 Neighbor-wise Collective on Mat 9376 9377 Input Parameters: 9378 + A - the matrix 9379 - R - the projection matrix 9380 9381 Output Parameters: 9382 . C - the product matrix 9383 9384 Notes: 9385 C must have been created by calling MatRARtSymbolic and must be destroyed by 9386 the user using MatDestroy(). 9387 9388 This routine is currently only implemented for pairs of AIJ matrices and classes 9389 which inherit from AIJ. C will be of type MATAIJ. 9390 9391 Level: intermediate 9392 9393 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9394 @*/ 9395 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9396 { 9397 PetscErrorCode ierr; 9398 9399 PetscFunctionBegin; 9400 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9401 PetscValidType(A,1); 9402 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9403 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9404 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9405 PetscValidType(R,2); 9406 MatCheckPreallocated(R,2); 9407 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9408 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9409 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9410 PetscValidType(C,3); 9411 MatCheckPreallocated(C,3); 9412 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9413 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); 9414 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); 9415 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); 9416 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); 9417 MatCheckPreallocated(A,1); 9418 9419 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9420 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9421 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9422 PetscFunctionReturn(0); 9423 } 9424 9425 /*@ 9426 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9427 9428 Neighbor-wise Collective on Mat 9429 9430 Input Parameters: 9431 + A - the matrix 9432 - R - the projection matrix 9433 9434 Output Parameters: 9435 . C - the (i,j) structure of the product matrix 9436 9437 Notes: 9438 C will be created and must be destroyed by the user with MatDestroy(). 9439 9440 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9441 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9442 this (i,j) structure by calling MatRARtNumeric(). 9443 9444 Level: intermediate 9445 9446 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9447 @*/ 9448 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9449 { 9450 PetscErrorCode ierr; 9451 9452 PetscFunctionBegin; 9453 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9454 PetscValidType(A,1); 9455 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9456 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9457 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9458 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9459 PetscValidType(R,2); 9460 MatCheckPreallocated(R,2); 9461 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9462 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9463 PetscValidPointer(C,3); 9464 9465 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); 9466 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); 9467 MatCheckPreallocated(A,1); 9468 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9469 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9470 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9471 9472 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9473 PetscFunctionReturn(0); 9474 } 9475 9476 /*@ 9477 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9478 9479 Neighbor-wise Collective on Mat 9480 9481 Input Parameters: 9482 + A - the left matrix 9483 . B - the right matrix 9484 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9485 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9486 if the result is a dense matrix this is irrelevent 9487 9488 Output Parameters: 9489 . C - the product matrix 9490 9491 Notes: 9492 Unless scall is MAT_REUSE_MATRIX C will be created. 9493 9494 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 9495 call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic() 9496 9497 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9498 actually needed. 9499 9500 If you have many matrices with the same non-zero structure to multiply, you 9501 should either 9502 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9503 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9504 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 9505 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9506 9507 Level: intermediate 9508 9509 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9510 @*/ 9511 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9512 { 9513 PetscErrorCode ierr; 9514 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9515 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9516 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9517 Mat T; 9518 PetscBool istrans; 9519 9520 PetscFunctionBegin; 9521 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9522 PetscValidType(A,1); 9523 MatCheckPreallocated(A,1); 9524 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9525 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9526 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9527 PetscValidType(B,2); 9528 MatCheckPreallocated(B,2); 9529 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9530 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9531 PetscValidPointer(C,3); 9532 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9533 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); 9534 ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9535 if (istrans) { 9536 ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 9537 ierr = MatTransposeMatMult(T,B,scall,fill,C);CHKERRQ(ierr); 9538 PetscFunctionReturn(0); 9539 } else { 9540 ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9541 if (istrans) { 9542 ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr); 9543 ierr = MatMatTransposeMult(A,T,scall,fill,C);CHKERRQ(ierr); 9544 PetscFunctionReturn(0); 9545 } 9546 } 9547 if (scall == MAT_REUSE_MATRIX) { 9548 PetscValidPointer(*C,5); 9549 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9550 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9551 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9552 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9553 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9554 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9555 PetscFunctionReturn(0); 9556 } 9557 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9558 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9559 9560 fA = A->ops->matmult; 9561 fB = B->ops->matmult; 9562 if (fB == fA && fB) mult = fB; 9563 else { 9564 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9565 char multname[256]; 9566 ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr); 9567 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9568 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9569 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9570 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9571 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9572 if (!mult) { 9573 ierr = PetscObjectQueryFunction((PetscObject)A,multname,&mult);CHKERRQ(ierr); 9574 } 9575 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); 9576 } 9577 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9578 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9579 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9580 PetscFunctionReturn(0); 9581 } 9582 9583 /*@ 9584 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9585 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9586 9587 Neighbor-wise Collective on Mat 9588 9589 Input Parameters: 9590 + A - the left matrix 9591 . B - the right matrix 9592 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9593 if C is a dense matrix this is irrelevent 9594 9595 Output Parameters: 9596 . C - the product matrix 9597 9598 Notes: 9599 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9600 actually needed. 9601 9602 This routine is currently implemented for 9603 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9604 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9605 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9606 9607 Level: intermediate 9608 9609 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, https://arxiv.org/abs/1006.4173 9610 We should incorporate them into PETSc. 9611 9612 .seealso: MatMatMult(), MatMatMultNumeric() 9613 @*/ 9614 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9615 { 9616 Mat T = NULL; 9617 PetscBool istrans; 9618 PetscErrorCode ierr; 9619 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9620 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9621 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9622 9623 PetscFunctionBegin; 9624 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9625 PetscValidType(A,1); 9626 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9627 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9628 9629 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9630 PetscValidType(B,2); 9631 MatCheckPreallocated(B,2); 9632 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9633 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9634 PetscValidPointer(C,3); 9635 9636 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); 9637 if (fill == PETSC_DEFAULT) fill = 2.0; 9638 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9639 MatCheckPreallocated(A,1); 9640 9641 Asymbolic = A->ops->matmultsymbolic; 9642 Bsymbolic = B->ops->matmultsymbolic; 9643 if (Asymbolic == Bsymbolic && Asymbolic) symbolic = Bsymbolic; 9644 else { /* dispatch based on the type of A and B */ 9645 char symbolicname[256]; 9646 ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9647 if (!istrans) { 9648 ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9649 ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9650 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9651 } else { 9652 ierr = PetscStrncpy(symbolicname,"MatTransposeMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9653 ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 9654 ierr = PetscStrlcat(symbolicname,((PetscObject)T)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9655 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9656 } 9657 ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9658 ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr); 9659 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9660 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); 9661 } 9662 ierr = PetscLogEventBegin(!T ? MAT_MatMultSymbolic : MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9663 *C = NULL; 9664 ierr = (*symbolic)(!T ? A : T,B,fill,C);CHKERRQ(ierr); 9665 ierr = PetscLogEventEnd(!T ? MAT_MatMultSymbolic : MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9666 PetscFunctionReturn(0); 9667 } 9668 9669 /*@ 9670 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9671 Call this routine after first calling MatMatMultSymbolic(). 9672 9673 Neighbor-wise Collective on Mat 9674 9675 Input Parameters: 9676 + A - the left matrix 9677 - B - the right matrix 9678 9679 Output Parameters: 9680 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9681 9682 Notes: 9683 C must have been created with MatMatMultSymbolic(). 9684 9685 This routine is currently implemented for 9686 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9687 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9688 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9689 9690 Level: intermediate 9691 9692 .seealso: MatMatMult(), MatMatMultSymbolic() 9693 @*/ 9694 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9695 { 9696 PetscErrorCode ierr; 9697 9698 PetscFunctionBegin; 9699 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr); 9700 PetscFunctionReturn(0); 9701 } 9702 9703 /*@ 9704 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9705 9706 Neighbor-wise Collective on Mat 9707 9708 Input Parameters: 9709 + A - the left matrix 9710 . B - the right matrix 9711 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9712 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9713 9714 Output Parameters: 9715 . C - the product matrix 9716 9717 Notes: 9718 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9719 9720 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9721 9722 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9723 actually needed. 9724 9725 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9726 and for pairs of MPIDense matrices. 9727 9728 Options Database Keys: 9729 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the 9730 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9731 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9732 9733 Level: intermediate 9734 9735 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9736 @*/ 9737 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9738 { 9739 PetscErrorCode ierr; 9740 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9741 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9742 Mat T; 9743 PetscBool istrans; 9744 9745 PetscFunctionBegin; 9746 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9747 PetscValidType(A,1); 9748 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9749 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9750 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9751 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9752 PetscValidType(B,2); 9753 MatCheckPreallocated(B,2); 9754 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9755 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9756 PetscValidPointer(C,3); 9757 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); 9758 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9759 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9760 MatCheckPreallocated(A,1); 9761 9762 ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9763 if (istrans) { 9764 ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr); 9765 ierr = MatMatMult(A,T,scall,fill,C);CHKERRQ(ierr); 9766 PetscFunctionReturn(0); 9767 } 9768 fA = A->ops->mattransposemult; 9769 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9770 fB = B->ops->mattransposemult; 9771 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9772 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); 9773 9774 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9775 if (scall == MAT_INITIAL_MATRIX) { 9776 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9777 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9778 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9779 } 9780 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9781 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 9782 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9783 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9784 PetscFunctionReturn(0); 9785 } 9786 9787 /*@ 9788 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9789 9790 Neighbor-wise Collective on Mat 9791 9792 Input Parameters: 9793 + A - the left matrix 9794 . B - the right matrix 9795 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9796 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9797 9798 Output Parameters: 9799 . C - the product matrix 9800 9801 Notes: 9802 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9803 9804 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9805 9806 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9807 actually needed. 9808 9809 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9810 which inherit from SeqAIJ. C will be of same type as the input matrices. 9811 9812 Level: intermediate 9813 9814 .seealso: MatMatMult(), MatMatTransposeMult(), MatPtAP() 9815 @*/ 9816 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9817 { 9818 PetscErrorCode ierr; 9819 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9820 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9821 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 9822 Mat T; 9823 PetscBool flg; 9824 9825 PetscFunctionBegin; 9826 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9827 PetscValidType(A,1); 9828 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9829 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9830 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9831 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9832 PetscValidType(B,2); 9833 MatCheckPreallocated(B,2); 9834 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9835 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9836 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); 9837 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9838 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9839 MatCheckPreallocated(A,1); 9840 9841 ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&flg);CHKERRQ(ierr); 9842 if (flg) { 9843 ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 9844 ierr = MatMatMult(T,B,scall,fill,C);CHKERRQ(ierr); 9845 PetscFunctionReturn(0); 9846 } 9847 if (scall == MAT_REUSE_MATRIX) { 9848 PetscValidPointer(*C,5); 9849 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9850 ierr = PetscObjectTypeCompareAny((PetscObject)*C,&flg,MATDENSE,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr); 9851 if (flg) { 9852 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9853 ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9854 ierr = (*(*C)->ops->transposematmultnumeric)(A,B,*C);CHKERRQ(ierr); 9855 ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9856 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9857 PetscFunctionReturn(0); 9858 } 9859 } 9860 9861 fA = A->ops->transposematmult; 9862 fB = B->ops->transposematmult; 9863 if (fB == fA && fA) transposematmult = fA; 9864 else { 9865 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9866 char multname[256]; 9867 ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr); 9868 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9869 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9870 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9871 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9872 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 9873 if (!transposematmult) { 9874 ierr = PetscObjectQueryFunction((PetscObject)A,multname,&transposematmult);CHKERRQ(ierr); 9875 } 9876 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); 9877 } 9878 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9879 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 9880 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9881 PetscFunctionReturn(0); 9882 } 9883 9884 /*@ 9885 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9886 9887 Neighbor-wise Collective on Mat 9888 9889 Input Parameters: 9890 + A - the left matrix 9891 . B - the middle matrix 9892 . C - the right matrix 9893 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9894 - 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 9895 if the result is a dense matrix this is irrelevent 9896 9897 Output Parameters: 9898 . D - the product matrix 9899 9900 Notes: 9901 Unless scall is MAT_REUSE_MATRIX D will be created. 9902 9903 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9904 9905 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9906 actually needed. 9907 9908 If you have many matrices with the same non-zero structure to multiply, you 9909 should use MAT_REUSE_MATRIX in all calls but the first or 9910 9911 Level: intermediate 9912 9913 .seealso: MatMatMult, MatPtAP() 9914 @*/ 9915 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9916 { 9917 PetscErrorCode ierr; 9918 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9919 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9920 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9921 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9922 9923 PetscFunctionBegin; 9924 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9925 PetscValidType(A,1); 9926 MatCheckPreallocated(A,1); 9927 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9928 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9929 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9930 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9931 PetscValidType(B,2); 9932 MatCheckPreallocated(B,2); 9933 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9934 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9935 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9936 PetscValidPointer(C,3); 9937 MatCheckPreallocated(C,3); 9938 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9939 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9940 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); 9941 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); 9942 if (scall == MAT_REUSE_MATRIX) { 9943 PetscValidPointer(*D,6); 9944 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 9945 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9946 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9947 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9948 PetscFunctionReturn(0); 9949 } 9950 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9951 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9952 9953 fA = A->ops->matmatmult; 9954 fB = B->ops->matmatmult; 9955 fC = C->ops->matmatmult; 9956 if (fA == fB && fA == fC) { 9957 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9958 mult = fA; 9959 } else { 9960 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 9961 char multname[256]; 9962 ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr); 9963 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9964 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9965 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9966 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9967 ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr); 9968 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); 9969 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9970 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); 9971 } 9972 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9973 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9974 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9975 PetscFunctionReturn(0); 9976 } 9977 9978 /*@ 9979 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9980 9981 Collective on Mat 9982 9983 Input Parameters: 9984 + mat - the matrix 9985 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9986 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 9987 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9988 9989 Output Parameter: 9990 . matredundant - redundant matrix 9991 9992 Notes: 9993 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9994 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9995 9996 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 9997 calling it. 9998 9999 Level: advanced 10000 10001 10002 .seealso: MatDestroy() 10003 @*/ 10004 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10005 { 10006 PetscErrorCode ierr; 10007 MPI_Comm comm; 10008 PetscMPIInt size; 10009 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10010 Mat_Redundant *redund=NULL; 10011 PetscSubcomm psubcomm=NULL; 10012 MPI_Comm subcomm_in=subcomm; 10013 Mat *matseq; 10014 IS isrow,iscol; 10015 PetscBool newsubcomm=PETSC_FALSE; 10016 10017 PetscFunctionBegin; 10018 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10019 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10020 PetscValidPointer(*matredundant,5); 10021 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10022 } 10023 10024 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10025 if (size == 1 || nsubcomm == 1) { 10026 if (reuse == MAT_INITIAL_MATRIX) { 10027 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 10028 } else { 10029 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"); 10030 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10031 } 10032 PetscFunctionReturn(0); 10033 } 10034 10035 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10036 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10037 MatCheckPreallocated(mat,1); 10038 10039 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10040 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10041 /* create psubcomm, then get subcomm */ 10042 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10043 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10044 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 10045 10046 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10047 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10048 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10049 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10050 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10051 newsubcomm = PETSC_TRUE; 10052 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10053 } 10054 10055 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10056 if (reuse == MAT_INITIAL_MATRIX) { 10057 mloc_sub = PETSC_DECIDE; 10058 nloc_sub = PETSC_DECIDE; 10059 if (bs < 1) { 10060 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10061 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 10062 } else { 10063 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10064 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 10065 } 10066 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10067 rstart = rend - mloc_sub; 10068 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10069 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10070 } else { /* reuse == MAT_REUSE_MATRIX */ 10071 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"); 10072 /* retrieve subcomm */ 10073 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10074 redund = (*matredundant)->redundant; 10075 isrow = redund->isrow; 10076 iscol = redund->iscol; 10077 matseq = redund->matseq; 10078 } 10079 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10080 10081 /* get matredundant over subcomm */ 10082 if (reuse == MAT_INITIAL_MATRIX) { 10083 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 10084 10085 /* create a supporting struct and attach it to C for reuse */ 10086 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10087 (*matredundant)->redundant = redund; 10088 redund->isrow = isrow; 10089 redund->iscol = iscol; 10090 redund->matseq = matseq; 10091 if (newsubcomm) { 10092 redund->subcomm = subcomm; 10093 } else { 10094 redund->subcomm = MPI_COMM_NULL; 10095 } 10096 } else { 10097 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10098 } 10099 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10100 PetscFunctionReturn(0); 10101 } 10102 10103 /*@C 10104 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10105 a given 'mat' object. Each submatrix can span multiple procs. 10106 10107 Collective on Mat 10108 10109 Input Parameters: 10110 + mat - the matrix 10111 . subcomm - the subcommunicator obtained by com_split(comm) 10112 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10113 10114 Output Parameter: 10115 . subMat - 'parallel submatrices each spans a given subcomm 10116 10117 Notes: 10118 The submatrix partition across processors is dictated by 'subComm' a 10119 communicator obtained by com_split(comm). The comm_split 10120 is not restriced to be grouped with consecutive original ranks. 10121 10122 Due the comm_split() usage, the parallel layout of the submatrices 10123 map directly to the layout of the original matrix [wrt the local 10124 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10125 into the 'DiagonalMat' of the subMat, hence it is used directly from 10126 the subMat. However the offDiagMat looses some columns - and this is 10127 reconstructed with MatSetValues() 10128 10129 Level: advanced 10130 10131 10132 .seealso: MatCreateSubMatrices() 10133 @*/ 10134 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10135 { 10136 PetscErrorCode ierr; 10137 PetscMPIInt commsize,subCommSize; 10138 10139 PetscFunctionBegin; 10140 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10141 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10142 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10143 10144 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"); 10145 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10146 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10147 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10148 PetscFunctionReturn(0); 10149 } 10150 10151 /*@ 10152 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10153 10154 Not Collective 10155 10156 Input Arguments: 10157 + mat - matrix to extract local submatrix from 10158 . isrow - local row indices for submatrix 10159 - iscol - local column indices for submatrix 10160 10161 Output Arguments: 10162 . submat - the submatrix 10163 10164 Level: intermediate 10165 10166 Notes: 10167 The submat should be returned with MatRestoreLocalSubMatrix(). 10168 10169 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10170 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10171 10172 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10173 MatSetValuesBlockedLocal() will also be implemented. 10174 10175 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10176 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10177 10178 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10179 @*/ 10180 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10181 { 10182 PetscErrorCode ierr; 10183 10184 PetscFunctionBegin; 10185 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10186 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10187 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10188 PetscCheckSameComm(isrow,2,iscol,3); 10189 PetscValidPointer(submat,4); 10190 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10191 10192 if (mat->ops->getlocalsubmatrix) { 10193 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10194 } else { 10195 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10196 } 10197 PetscFunctionReturn(0); 10198 } 10199 10200 /*@ 10201 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10202 10203 Not Collective 10204 10205 Input Arguments: 10206 mat - matrix to extract local submatrix from 10207 isrow - local row indices for submatrix 10208 iscol - local column indices for submatrix 10209 submat - the submatrix 10210 10211 Level: intermediate 10212 10213 .seealso: MatGetLocalSubMatrix() 10214 @*/ 10215 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10216 { 10217 PetscErrorCode ierr; 10218 10219 PetscFunctionBegin; 10220 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10221 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10222 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10223 PetscCheckSameComm(isrow,2,iscol,3); 10224 PetscValidPointer(submat,4); 10225 if (*submat) { 10226 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10227 } 10228 10229 if (mat->ops->restorelocalsubmatrix) { 10230 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10231 } else { 10232 ierr = MatDestroy(submat);CHKERRQ(ierr); 10233 } 10234 *submat = NULL; 10235 PetscFunctionReturn(0); 10236 } 10237 10238 /* --------------------------------------------------------*/ 10239 /*@ 10240 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10241 10242 Collective on Mat 10243 10244 Input Parameter: 10245 . mat - the matrix 10246 10247 Output Parameter: 10248 . is - if any rows have zero diagonals this contains the list of them 10249 10250 Level: developer 10251 10252 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10253 @*/ 10254 PetscErrorCode MatFindZeroDiagonals(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->findzerodiagonals) { 10265 Vec diag; 10266 const PetscScalar *a; 10267 PetscInt *rows; 10268 PetscInt rStart, rEnd, r, nrow = 0; 10269 10270 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10271 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10272 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10273 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10274 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10275 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10276 nrow = 0; 10277 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10278 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10279 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10280 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10281 } else { 10282 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10283 } 10284 PetscFunctionReturn(0); 10285 } 10286 10287 /*@ 10288 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10289 10290 Collective on Mat 10291 10292 Input Parameter: 10293 . mat - the matrix 10294 10295 Output Parameter: 10296 . is - contains the list of rows with off block diagonal entries 10297 10298 Level: developer 10299 10300 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10301 @*/ 10302 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10303 { 10304 PetscErrorCode ierr; 10305 10306 PetscFunctionBegin; 10307 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10308 PetscValidType(mat,1); 10309 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10310 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10311 10312 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10313 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10314 PetscFunctionReturn(0); 10315 } 10316 10317 /*@C 10318 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10319 10320 Collective on Mat 10321 10322 Input Parameters: 10323 . mat - the matrix 10324 10325 Output Parameters: 10326 . values - the block inverses in column major order (FORTRAN-like) 10327 10328 Note: 10329 This routine is not available from Fortran. 10330 10331 Level: advanced 10332 10333 .seealso: MatInvertBockDiagonalMat 10334 @*/ 10335 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10336 { 10337 PetscErrorCode ierr; 10338 10339 PetscFunctionBegin; 10340 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10341 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10342 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10343 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10344 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10345 PetscFunctionReturn(0); 10346 } 10347 10348 /*@C 10349 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries. 10350 10351 Collective on Mat 10352 10353 Input Parameters: 10354 + mat - the matrix 10355 . nblocks - the number of blocks 10356 - bsizes - the size of each block 10357 10358 Output Parameters: 10359 . values - the block inverses in column major order (FORTRAN-like) 10360 10361 Note: 10362 This routine is not available from Fortran. 10363 10364 Level: advanced 10365 10366 .seealso: MatInvertBockDiagonal() 10367 @*/ 10368 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10369 { 10370 PetscErrorCode ierr; 10371 10372 PetscFunctionBegin; 10373 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10374 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10375 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10376 if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10377 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 10378 PetscFunctionReturn(0); 10379 } 10380 10381 /*@ 10382 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10383 10384 Collective on Mat 10385 10386 Input Parameters: 10387 . A - the matrix 10388 10389 Output Parameters: 10390 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10391 10392 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10393 10394 Level: advanced 10395 10396 .seealso: MatInvertBockDiagonal() 10397 @*/ 10398 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10399 { 10400 PetscErrorCode ierr; 10401 const PetscScalar *vals; 10402 PetscInt *dnnz; 10403 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10404 10405 PetscFunctionBegin; 10406 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10407 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10408 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10409 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10410 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10411 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10412 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10413 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10414 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10415 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10416 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10417 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10418 for (i = rstart/bs; i < rend/bs; i++) { 10419 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10420 } 10421 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10422 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10423 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10424 PetscFunctionReturn(0); 10425 } 10426 10427 /*@C 10428 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10429 via MatTransposeColoringCreate(). 10430 10431 Collective on MatTransposeColoring 10432 10433 Input Parameter: 10434 . c - coloring context 10435 10436 Level: intermediate 10437 10438 .seealso: MatTransposeColoringCreate() 10439 @*/ 10440 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10441 { 10442 PetscErrorCode ierr; 10443 MatTransposeColoring matcolor=*c; 10444 10445 PetscFunctionBegin; 10446 if (!matcolor) PetscFunctionReturn(0); 10447 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10448 10449 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10450 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10451 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10452 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10453 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10454 if (matcolor->brows>0) { 10455 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10456 } 10457 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10458 PetscFunctionReturn(0); 10459 } 10460 10461 /*@C 10462 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10463 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10464 MatTransposeColoring to sparse B. 10465 10466 Collective on MatTransposeColoring 10467 10468 Input Parameters: 10469 + B - sparse matrix B 10470 . Btdense - symbolic dense matrix B^T 10471 - coloring - coloring context created with MatTransposeColoringCreate() 10472 10473 Output Parameter: 10474 . Btdense - dense matrix B^T 10475 10476 Level: advanced 10477 10478 Notes: 10479 These are used internally for some implementations of MatRARt() 10480 10481 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10482 10483 @*/ 10484 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10485 { 10486 PetscErrorCode ierr; 10487 10488 PetscFunctionBegin; 10489 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10490 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10491 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10492 10493 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10494 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10495 PetscFunctionReturn(0); 10496 } 10497 10498 /*@C 10499 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10500 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10501 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10502 Csp from Cden. 10503 10504 Collective on MatTransposeColoring 10505 10506 Input Parameters: 10507 + coloring - coloring context created with MatTransposeColoringCreate() 10508 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10509 10510 Output Parameter: 10511 . Csp - sparse matrix 10512 10513 Level: advanced 10514 10515 Notes: 10516 These are used internally for some implementations of MatRARt() 10517 10518 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10519 10520 @*/ 10521 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10522 { 10523 PetscErrorCode ierr; 10524 10525 PetscFunctionBegin; 10526 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10527 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10528 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10529 10530 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10531 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10532 PetscFunctionReturn(0); 10533 } 10534 10535 /*@C 10536 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10537 10538 Collective on Mat 10539 10540 Input Parameters: 10541 + mat - the matrix product C 10542 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10543 10544 Output Parameter: 10545 . color - the new coloring context 10546 10547 Level: intermediate 10548 10549 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10550 MatTransColoringApplyDenToSp() 10551 @*/ 10552 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10553 { 10554 MatTransposeColoring c; 10555 MPI_Comm comm; 10556 PetscErrorCode ierr; 10557 10558 PetscFunctionBegin; 10559 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10560 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10561 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10562 10563 c->ctype = iscoloring->ctype; 10564 if (mat->ops->transposecoloringcreate) { 10565 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10566 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10567 10568 *color = c; 10569 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10570 PetscFunctionReturn(0); 10571 } 10572 10573 /*@ 10574 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10575 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10576 same, otherwise it will be larger 10577 10578 Not Collective 10579 10580 Input Parameter: 10581 . A - the matrix 10582 10583 Output Parameter: 10584 . state - the current state 10585 10586 Notes: 10587 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10588 different matrices 10589 10590 Level: intermediate 10591 10592 @*/ 10593 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10594 { 10595 PetscFunctionBegin; 10596 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10597 *state = mat->nonzerostate; 10598 PetscFunctionReturn(0); 10599 } 10600 10601 /*@ 10602 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10603 matrices from each processor 10604 10605 Collective 10606 10607 Input Parameters: 10608 + comm - the communicators the parallel matrix will live on 10609 . seqmat - the input sequential matrices 10610 . n - number of local columns (or PETSC_DECIDE) 10611 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10612 10613 Output Parameter: 10614 . mpimat - the parallel matrix generated 10615 10616 Level: advanced 10617 10618 Notes: 10619 The number of columns of the matrix in EACH processor MUST be the same. 10620 10621 @*/ 10622 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10623 { 10624 PetscErrorCode ierr; 10625 10626 PetscFunctionBegin; 10627 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10628 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"); 10629 10630 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10631 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10632 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10633 PetscFunctionReturn(0); 10634 } 10635 10636 /*@ 10637 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10638 ranks' ownership ranges. 10639 10640 Collective on A 10641 10642 Input Parameters: 10643 + A - the matrix to create subdomains from 10644 - N - requested number of subdomains 10645 10646 10647 Output Parameters: 10648 + n - number of subdomains resulting on this rank 10649 - iss - IS list with indices of subdomains on this rank 10650 10651 Level: advanced 10652 10653 Notes: 10654 number of subdomains must be smaller than the communicator size 10655 @*/ 10656 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10657 { 10658 MPI_Comm comm,subcomm; 10659 PetscMPIInt size,rank,color; 10660 PetscInt rstart,rend,k; 10661 PetscErrorCode ierr; 10662 10663 PetscFunctionBegin; 10664 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10665 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10666 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10667 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); 10668 *n = 1; 10669 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10670 color = rank/k; 10671 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10672 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10673 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10674 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10675 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10676 PetscFunctionReturn(0); 10677 } 10678 10679 /*@ 10680 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10681 10682 If the interpolation and restriction operators are the same, uses MatPtAP. 10683 If they are not the same, use MatMatMatMult. 10684 10685 Once the coarse grid problem is constructed, correct for interpolation operators 10686 that are not of full rank, which can legitimately happen in the case of non-nested 10687 geometric multigrid. 10688 10689 Input Parameters: 10690 + restrct - restriction operator 10691 . dA - fine grid matrix 10692 . interpolate - interpolation operator 10693 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10694 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10695 10696 Output Parameters: 10697 . A - the Galerkin coarse matrix 10698 10699 Options Database Key: 10700 . -pc_mg_galerkin <both,pmat,mat,none> 10701 10702 Level: developer 10703 10704 .seealso: MatPtAP(), MatMatMatMult() 10705 @*/ 10706 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10707 { 10708 PetscErrorCode ierr; 10709 IS zerorows; 10710 Vec diag; 10711 10712 PetscFunctionBegin; 10713 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10714 /* Construct the coarse grid matrix */ 10715 if (interpolate == restrct) { 10716 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10717 } else { 10718 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10719 } 10720 10721 /* If the interpolation matrix is not of full rank, A will have zero rows. 10722 This can legitimately happen in the case of non-nested geometric multigrid. 10723 In that event, we set the rows of the matrix to the rows of the identity, 10724 ignoring the equations (as the RHS will also be zero). */ 10725 10726 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10727 10728 if (zerorows != NULL) { /* if there are any zero rows */ 10729 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10730 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10731 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10732 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10733 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10734 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10735 } 10736 PetscFunctionReturn(0); 10737 } 10738 10739 /*@C 10740 MatSetOperation - Allows user to set a matrix operation for any matrix type 10741 10742 Logically Collective on Mat 10743 10744 Input Parameters: 10745 + mat - the matrix 10746 . op - the name of the operation 10747 - f - the function that provides the operation 10748 10749 Level: developer 10750 10751 Usage: 10752 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10753 $ ierr = MatCreateXXX(comm,...&A); 10754 $ ierr = MatSetOperation(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 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10763 sequence as the usual matrix interface routines, since they 10764 are intended to be accessed via the usual matrix interface 10765 routines, e.g., 10766 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10767 10768 In particular each function MUST return an error code of 0 on success and 10769 nonzero on failure. 10770 10771 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10772 10773 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10774 @*/ 10775 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10776 { 10777 PetscFunctionBegin; 10778 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10779 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10780 mat->ops->viewnative = mat->ops->view; 10781 } 10782 (((void(**)(void))mat->ops)[op]) = f; 10783 PetscFunctionReturn(0); 10784 } 10785 10786 /*@C 10787 MatGetOperation - Gets a matrix operation for any matrix type. 10788 10789 Not Collective 10790 10791 Input Parameters: 10792 + mat - the matrix 10793 - op - the name of the operation 10794 10795 Output Parameter: 10796 . f - the function that provides the operation 10797 10798 Level: developer 10799 10800 Usage: 10801 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10802 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10803 10804 Notes: 10805 See the file include/petscmat.h for a complete list of matrix 10806 operations, which all have the form MATOP_<OPERATION>, where 10807 <OPERATION> is the name (in all capital letters) of the 10808 user interface routine (e.g., MatMult() -> MATOP_MULT). 10809 10810 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10811 10812 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 10813 @*/ 10814 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10815 { 10816 PetscFunctionBegin; 10817 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10818 *f = (((void (**)(void))mat->ops)[op]); 10819 PetscFunctionReturn(0); 10820 } 10821 10822 /*@ 10823 MatHasOperation - Determines whether the given matrix supports the particular 10824 operation. 10825 10826 Not Collective 10827 10828 Input Parameters: 10829 + mat - the matrix 10830 - op - the operation, for example, MATOP_GET_DIAGONAL 10831 10832 Output Parameter: 10833 . has - either PETSC_TRUE or PETSC_FALSE 10834 10835 Level: advanced 10836 10837 Notes: 10838 See the file include/petscmat.h for a complete list of matrix 10839 operations, which all have the form MATOP_<OPERATION>, where 10840 <OPERATION> is the name (in all capital letters) of the 10841 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10842 10843 .seealso: MatCreateShell() 10844 @*/ 10845 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10846 { 10847 PetscErrorCode ierr; 10848 10849 PetscFunctionBegin; 10850 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10851 PetscValidType(mat,1); 10852 PetscValidPointer(has,3); 10853 if (mat->ops->hasoperation) { 10854 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 10855 } else { 10856 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10857 else { 10858 *has = PETSC_FALSE; 10859 if (op == MATOP_CREATE_SUBMATRIX) { 10860 PetscMPIInt size; 10861 10862 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10863 if (size == 1) { 10864 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 10865 } 10866 } 10867 } 10868 } 10869 PetscFunctionReturn(0); 10870 } 10871 10872 /*@ 10873 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10874 of the matrix are congruent 10875 10876 Collective on mat 10877 10878 Input Parameters: 10879 . mat - the matrix 10880 10881 Output Parameter: 10882 . cong - either PETSC_TRUE or PETSC_FALSE 10883 10884 Level: beginner 10885 10886 Notes: 10887 10888 .seealso: MatCreate(), MatSetSizes() 10889 @*/ 10890 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 10891 { 10892 PetscErrorCode ierr; 10893 10894 PetscFunctionBegin; 10895 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10896 PetscValidType(mat,1); 10897 PetscValidPointer(cong,2); 10898 if (!mat->rmap || !mat->cmap) { 10899 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10900 PetscFunctionReturn(0); 10901 } 10902 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10903 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 10904 if (*cong) mat->congruentlayouts = 1; 10905 else mat->congruentlayouts = 0; 10906 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10907 PetscFunctionReturn(0); 10908 } 10909 10910 /*@ 10911 MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse, 10912 e.g., matrx product of MatPtAP. 10913 10914 Collective on mat 10915 10916 Input Parameters: 10917 . mat - the matrix 10918 10919 Output Parameter: 10920 . mat - the matrix with intermediate data structures released 10921 10922 Level: advanced 10923 10924 Notes: 10925 10926 .seealso: MatPtAP(), MatMatMult() 10927 @*/ 10928 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat) 10929 { 10930 PetscErrorCode ierr; 10931 10932 PetscFunctionBegin; 10933 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10934 PetscValidType(mat,1); 10935 if (mat->ops->freeintermediatedatastructures) { 10936 ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr); 10937 } 10938 PetscFunctionReturn(0); 10939 } 10940