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