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