1 /* 2 This is where the abstract matrix operations are defined 3 */ 4 5 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 6 #include <petsc/private/isimpl.h> 7 #include <petsc/private/vecimpl.h> 8 9 /* Logging support */ 10 PetscClassId MAT_CLASSID; 11 PetscClassId MAT_COLORING_CLASSID; 12 PetscClassId MAT_FDCOLORING_CLASSID; 13 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 14 15 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose; 16 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 17 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 18 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 19 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 20 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 21 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 22 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat; 23 PetscLogEvent MAT_TransposeColoringCreate; 24 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 25 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 26 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 27 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 28 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 29 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 30 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols; 31 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 32 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 33 PetscLogEvent MAT_GetMultiProcBlock; 34 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch; 35 PetscLogEvent MAT_ViennaCLCopyToGPU; 36 PetscLogEvent MAT_DenseCopyToGPU, MAT_DenseCopyFromGPU; 37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 38 PetscLogEvent MAT_FactorFactS,MAT_FactorInvS; 39 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 40 41 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0}; 42 43 /*@ 44 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations, 45 for sparse matrices that already have locations it fills the locations with random numbers 46 47 Logically Collective on Mat 48 49 Input Parameters: 50 + x - the matrix 51 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 52 it will create one internally. 53 54 Output Parameter: 55 . x - the matrix 56 57 Example of Usage: 58 .vb 59 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 60 MatSetRandom(x,rctx); 61 PetscRandomDestroy(rctx); 62 .ve 63 64 Level: intermediate 65 66 67 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy() 68 @*/ 69 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 70 { 71 PetscErrorCode ierr; 72 PetscRandom randObj = NULL; 73 74 PetscFunctionBegin; 75 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 76 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 77 PetscValidType(x,1); 78 79 if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 80 81 if (!rctx) { 82 MPI_Comm comm; 83 ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 84 ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr); 85 ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr); 86 rctx = randObj; 87 } 88 89 ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 90 ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr); 91 ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 92 93 ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 94 ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 95 ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr); 96 PetscFunctionReturn(0); 97 } 98 99 /*@ 100 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 101 102 Logically Collective on Mat 103 104 Input Parameters: 105 . mat - the factored matrix 106 107 Output Parameter: 108 + pivot - the pivot value computed 109 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 110 the share the matrix 111 112 Level: advanced 113 114 Notes: 115 This routine does not work for factorizations done with external packages. 116 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 117 118 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 119 120 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 121 @*/ 122 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 123 { 124 PetscFunctionBegin; 125 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 126 *pivot = mat->factorerror_zeropivot_value; 127 *row = mat->factorerror_zeropivot_row; 128 PetscFunctionReturn(0); 129 } 130 131 /*@ 132 MatFactorGetError - gets the error code from a factorization 133 134 Logically Collective on Mat 135 136 Input Parameters: 137 . mat - the factored matrix 138 139 Output Parameter: 140 . err - the error code 141 142 Level: advanced 143 144 Notes: 145 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 146 147 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 148 @*/ 149 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 150 { 151 PetscFunctionBegin; 152 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 153 *err = mat->factorerrortype; 154 PetscFunctionReturn(0); 155 } 156 157 /*@ 158 MatFactorClearError - clears the error code in a factorization 159 160 Logically Collective on Mat 161 162 Input Parameter: 163 . mat - the factored matrix 164 165 Level: developer 166 167 Notes: 168 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 169 170 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot() 171 @*/ 172 PetscErrorCode MatFactorClearError(Mat mat) 173 { 174 PetscFunctionBegin; 175 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 176 mat->factorerrortype = MAT_FACTOR_NOERROR; 177 mat->factorerror_zeropivot_value = 0.0; 178 mat->factorerror_zeropivot_row = 0; 179 PetscFunctionReturn(0); 180 } 181 182 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 183 { 184 PetscErrorCode ierr; 185 Vec r,l; 186 const PetscScalar *al; 187 PetscInt i,nz,gnz,N,n; 188 189 PetscFunctionBegin; 190 ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr); 191 if (!cols) { /* nonzero rows */ 192 ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 193 ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr); 194 ierr = VecSet(l,0.0);CHKERRQ(ierr); 195 ierr = VecSetRandom(r,NULL);CHKERRQ(ierr); 196 ierr = MatMult(mat,r,l);CHKERRQ(ierr); 197 ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr); 198 } else { /* nonzero columns */ 199 ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr); 200 ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr); 201 ierr = VecSet(r,0.0);CHKERRQ(ierr); 202 ierr = VecSetRandom(l,NULL);CHKERRQ(ierr); 203 ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr); 204 ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr); 205 } 206 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 207 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 208 ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 209 if (gnz != N) { 210 PetscInt *nzr; 211 ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr); 212 if (nz) { 213 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 214 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 215 } 216 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr); 217 } else *nonzero = NULL; 218 if (!cols) { /* nonzero rows */ 219 ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr); 220 } else { 221 ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr); 222 } 223 ierr = VecDestroy(&l);CHKERRQ(ierr); 224 ierr = VecDestroy(&r);CHKERRQ(ierr); 225 PetscFunctionReturn(0); 226 } 227 228 /*@ 229 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 230 231 Input Parameter: 232 . A - the matrix 233 234 Output Parameter: 235 . keptrows - the rows that are not completely zero 236 237 Notes: 238 keptrows is set to NULL if all rows are nonzero. 239 240 Level: intermediate 241 242 @*/ 243 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 244 { 245 PetscErrorCode ierr; 246 247 PetscFunctionBegin; 248 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 249 PetscValidType(mat,1); 250 PetscValidPointer(keptrows,2); 251 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 252 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 253 if (!mat->ops->findnonzerorows) { 254 ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr); 255 } else { 256 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr); 257 } 258 PetscFunctionReturn(0); 259 } 260 261 /*@ 262 MatFindZeroRows - Locate all rows that are completely zero in the matrix 263 264 Input Parameter: 265 . A - the matrix 266 267 Output Parameter: 268 . zerorows - the rows that are completely zero 269 270 Notes: 271 zerorows is set to NULL if no rows are zero. 272 273 Level: intermediate 274 275 @*/ 276 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 277 { 278 PetscErrorCode ierr; 279 IS keptrows; 280 PetscInt m, n; 281 282 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 283 PetscValidType(mat,1); 284 285 ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr); 286 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 287 In keeping with this convention, we set zerorows to NULL if there are no zero 288 rows. */ 289 if (keptrows == NULL) { 290 *zerorows = NULL; 291 } else { 292 ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr); 293 ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr); 294 ierr = ISDestroy(&keptrows);CHKERRQ(ierr); 295 } 296 PetscFunctionReturn(0); 297 } 298 299 /*@ 300 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 301 302 Not Collective 303 304 Input Parameters: 305 . A - the matrix 306 307 Output Parameters: 308 . a - the diagonal part (which is a SEQUENTIAL matrix) 309 310 Notes: 311 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 312 Use caution, as the reference count on the returned matrix is not incremented and it is used as 313 part of the containing MPI Mat's normal operation. 314 315 Level: advanced 316 317 @*/ 318 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 319 { 320 PetscErrorCode ierr; 321 322 PetscFunctionBegin; 323 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 324 PetscValidType(A,1); 325 PetscValidPointer(a,3); 326 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 327 if (!A->ops->getdiagonalblock) { 328 PetscMPIInt size; 329 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 330 if (size == 1) { 331 *a = A; 332 PetscFunctionReturn(0); 333 } else SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for matrix type %s",((PetscObject)A)->type_name); 334 } 335 ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr); 336 PetscFunctionReturn(0); 337 } 338 339 /*@ 340 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 341 342 Collective on Mat 343 344 Input Parameters: 345 . mat - the matrix 346 347 Output Parameter: 348 . trace - the sum of the diagonal entries 349 350 Level: advanced 351 352 @*/ 353 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 354 { 355 PetscErrorCode ierr; 356 Vec diag; 357 358 PetscFunctionBegin; 359 ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr); 360 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr); 361 ierr = VecSum(diag,trace);CHKERRQ(ierr); 362 ierr = VecDestroy(&diag);CHKERRQ(ierr); 363 PetscFunctionReturn(0); 364 } 365 366 /*@ 367 MatRealPart - Zeros out the imaginary part of the matrix 368 369 Logically Collective on Mat 370 371 Input Parameters: 372 . mat - the matrix 373 374 Level: advanced 375 376 377 .seealso: MatImaginaryPart() 378 @*/ 379 PetscErrorCode MatRealPart(Mat mat) 380 { 381 PetscErrorCode ierr; 382 383 PetscFunctionBegin; 384 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 385 PetscValidType(mat,1); 386 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 387 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 388 if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 389 MatCheckPreallocated(mat,1); 390 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr); 391 PetscFunctionReturn(0); 392 } 393 394 /*@C 395 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 396 397 Collective on Mat 398 399 Input Parameter: 400 . mat - the matrix 401 402 Output Parameters: 403 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 404 - ghosts - the global indices of the ghost points 405 406 Notes: 407 the nghosts and ghosts are suitable to pass into VecCreateGhost() 408 409 Level: advanced 410 411 @*/ 412 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 413 { 414 PetscErrorCode ierr; 415 416 PetscFunctionBegin; 417 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 418 PetscValidType(mat,1); 419 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 420 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 421 if (!mat->ops->getghosts) { 422 if (nghosts) *nghosts = 0; 423 if (ghosts) *ghosts = 0; 424 } else { 425 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr); 426 } 427 PetscFunctionReturn(0); 428 } 429 430 431 /*@ 432 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 433 434 Logically Collective on Mat 435 436 Input Parameters: 437 . mat - the matrix 438 439 Level: advanced 440 441 442 .seealso: MatRealPart() 443 @*/ 444 PetscErrorCode MatImaginaryPart(Mat mat) 445 { 446 PetscErrorCode ierr; 447 448 PetscFunctionBegin; 449 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 450 PetscValidType(mat,1); 451 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 452 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 453 if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 454 MatCheckPreallocated(mat,1); 455 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr); 456 PetscFunctionReturn(0); 457 } 458 459 /*@ 460 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 461 462 Not Collective 463 464 Input Parameter: 465 . mat - the matrix 466 467 Output Parameters: 468 + missing - is any diagonal missing 469 - dd - first diagonal entry that is missing (optional) on this process 470 471 Level: advanced 472 473 474 .seealso: MatRealPart() 475 @*/ 476 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 477 { 478 PetscErrorCode ierr; 479 480 PetscFunctionBegin; 481 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 482 PetscValidType(mat,1); 483 PetscValidPointer(missing,2); 484 if (!mat->assembled) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix %s",((PetscObject)mat)->type_name); 485 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 486 if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 487 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr); 488 PetscFunctionReturn(0); 489 } 490 491 /*@C 492 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 493 for each row that you get to ensure that your application does 494 not bleed memory. 495 496 Not Collective 497 498 Input Parameters: 499 + mat - the matrix 500 - row - the row to get 501 502 Output Parameters: 503 + ncols - if not NULL, the number of nonzeros in the row 504 . cols - if not NULL, the column numbers 505 - vals - if not NULL, the values 506 507 Notes: 508 This routine is provided for people who need to have direct access 509 to the structure of a matrix. We hope that we provide enough 510 high-level matrix routines that few users will need it. 511 512 MatGetRow() always returns 0-based column indices, regardless of 513 whether the internal representation is 0-based (default) or 1-based. 514 515 For better efficiency, set cols and/or vals to NULL if you do 516 not wish to extract these quantities. 517 518 The user can only examine the values extracted with MatGetRow(); 519 the values cannot be altered. To change the matrix entries, one 520 must use MatSetValues(). 521 522 You can only have one call to MatGetRow() outstanding for a particular 523 matrix at a time, per processor. MatGetRow() can only obtain rows 524 associated with the given processor, it cannot get rows from the 525 other processors; for that we suggest using MatCreateSubMatrices(), then 526 MatGetRow() on the submatrix. The row index passed to MatGetRow() 527 is in the global number of rows. 528 529 Fortran Notes: 530 The calling sequence from Fortran is 531 .vb 532 MatGetRow(matrix,row,ncols,cols,values,ierr) 533 Mat matrix (input) 534 integer row (input) 535 integer ncols (output) 536 integer cols(maxcols) (output) 537 double precision (or double complex) values(maxcols) output 538 .ve 539 where maxcols >= maximum nonzeros in any row of the matrix. 540 541 542 Caution: 543 Do not try to change the contents of the output arrays (cols and vals). 544 In some cases, this may corrupt the matrix. 545 546 Level: advanced 547 548 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal() 549 @*/ 550 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 551 { 552 PetscErrorCode ierr; 553 PetscInt incols; 554 555 PetscFunctionBegin; 556 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 557 PetscValidType(mat,1); 558 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 559 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 560 if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 561 MatCheckPreallocated(mat,1); 562 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 563 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr); 564 if (ncols) *ncols = incols; 565 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 566 PetscFunctionReturn(0); 567 } 568 569 /*@ 570 MatConjugate - replaces the matrix values with their complex conjugates 571 572 Logically Collective on Mat 573 574 Input Parameters: 575 . mat - the matrix 576 577 Level: advanced 578 579 .seealso: VecConjugate() 580 @*/ 581 PetscErrorCode MatConjugate(Mat mat) 582 { 583 #if defined(PETSC_USE_COMPLEX) 584 PetscErrorCode ierr; 585 586 PetscFunctionBegin; 587 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 588 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 589 if (!mat->ops->conjugate) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for matrix type %s, send email to petsc-maint@mcs.anl.gov",((PetscObject)mat)->type_name); 590 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr); 591 #else 592 PetscFunctionBegin; 593 #endif 594 PetscFunctionReturn(0); 595 } 596 597 /*@C 598 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 599 600 Not Collective 601 602 Input Parameters: 603 + mat - the matrix 604 . row - the row to get 605 . ncols, cols - the number of nonzeros and their columns 606 - vals - if nonzero the column values 607 608 Notes: 609 This routine should be called after you have finished examining the entries. 610 611 This routine zeros out ncols, cols, and vals. This is to prevent accidental 612 us of the array after it has been restored. If you pass NULL, it will 613 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 614 615 Fortran Notes: 616 The calling sequence from Fortran is 617 .vb 618 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 619 Mat matrix (input) 620 integer row (input) 621 integer ncols (output) 622 integer cols(maxcols) (output) 623 double precision (or double complex) values(maxcols) output 624 .ve 625 Where maxcols >= maximum nonzeros in any row of the matrix. 626 627 In Fortran MatRestoreRow() MUST be called after MatGetRow() 628 before another call to MatGetRow() can be made. 629 630 Level: advanced 631 632 .seealso: MatGetRow() 633 @*/ 634 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 635 { 636 PetscErrorCode ierr; 637 638 PetscFunctionBegin; 639 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 640 if (ncols) PetscValidIntPointer(ncols,3); 641 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 642 if (!mat->ops->restorerow) PetscFunctionReturn(0); 643 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 644 if (ncols) *ncols = 0; 645 if (cols) *cols = NULL; 646 if (vals) *vals = NULL; 647 PetscFunctionReturn(0); 648 } 649 650 /*@ 651 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 652 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 653 654 Not Collective 655 656 Input Parameters: 657 . mat - the matrix 658 659 Notes: 660 The flag is to ensure that users are aware of MatGetRow() only provides the upper triangular part of the row for the matrices in MATSBAIJ format. 661 662 Level: advanced 663 664 .seealso: MatRestoreRowUpperTriangular() 665 @*/ 666 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 667 { 668 PetscErrorCode ierr; 669 670 PetscFunctionBegin; 671 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 672 PetscValidType(mat,1); 673 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 674 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 675 MatCheckPreallocated(mat,1); 676 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 677 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr); 678 PetscFunctionReturn(0); 679 } 680 681 /*@ 682 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 683 684 Not Collective 685 686 Input Parameters: 687 . mat - the matrix 688 689 Notes: 690 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 691 692 693 Level: advanced 694 695 .seealso: MatGetRowUpperTriangular() 696 @*/ 697 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 698 { 699 PetscErrorCode ierr; 700 701 PetscFunctionBegin; 702 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 703 PetscValidType(mat,1); 704 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 705 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 706 MatCheckPreallocated(mat,1); 707 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 708 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr); 709 PetscFunctionReturn(0); 710 } 711 712 /*@C 713 MatSetOptionsPrefix - Sets the prefix used for searching for all 714 Mat options in the database. 715 716 Logically Collective on Mat 717 718 Input Parameter: 719 + A - the Mat context 720 - prefix - the prefix to prepend to all option names 721 722 Notes: 723 A hyphen (-) must NOT be given at the beginning of the prefix name. 724 The first character of all runtime options is AUTOMATICALLY the hyphen. 725 726 Level: advanced 727 728 .seealso: MatSetFromOptions() 729 @*/ 730 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 731 { 732 PetscErrorCode ierr; 733 734 PetscFunctionBegin; 735 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 736 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 737 PetscFunctionReturn(0); 738 } 739 740 /*@C 741 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 742 Mat options in the database. 743 744 Logically Collective on Mat 745 746 Input Parameters: 747 + A - the Mat context 748 - prefix - the prefix to prepend to all option names 749 750 Notes: 751 A hyphen (-) must NOT be given at the beginning of the prefix name. 752 The first character of all runtime options is AUTOMATICALLY the hyphen. 753 754 Level: advanced 755 756 .seealso: MatGetOptionsPrefix() 757 @*/ 758 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 759 { 760 PetscErrorCode ierr; 761 762 PetscFunctionBegin; 763 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 764 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 765 PetscFunctionReturn(0); 766 } 767 768 /*@C 769 MatGetOptionsPrefix - Gets the prefix used for searching for all 770 Mat options in the database. 771 772 Not Collective 773 774 Input Parameter: 775 . A - the Mat context 776 777 Output Parameter: 778 . prefix - pointer to the prefix string used 779 780 Notes: 781 On the fortran side, the user should pass in a string 'prefix' of 782 sufficient length to hold the prefix. 783 784 Level: advanced 785 786 .seealso: MatAppendOptionsPrefix() 787 @*/ 788 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 789 { 790 PetscErrorCode ierr; 791 792 PetscFunctionBegin; 793 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 794 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 795 PetscFunctionReturn(0); 796 } 797 798 /*@ 799 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 800 801 Collective on Mat 802 803 Input Parameters: 804 . A - the Mat context 805 806 Notes: 807 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 808 Currently support MPIAIJ and SEQAIJ. 809 810 Level: beginner 811 812 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation() 813 @*/ 814 PetscErrorCode MatResetPreallocation(Mat A) 815 { 816 PetscErrorCode ierr; 817 818 PetscFunctionBegin; 819 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 820 PetscValidType(A,1); 821 ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr); 822 PetscFunctionReturn(0); 823 } 824 825 826 /*@ 827 MatSetUp - Sets up the internal matrix data structures for the later use. 828 829 Collective on Mat 830 831 Input Parameters: 832 . A - the Mat context 833 834 Notes: 835 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 836 837 If a suitable preallocation routine is used, this function does not need to be called. 838 839 See the Performance chapter of the PETSc users manual for how to preallocate matrices 840 841 Level: beginner 842 843 .seealso: MatCreate(), MatDestroy() 844 @*/ 845 PetscErrorCode MatSetUp(Mat A) 846 { 847 PetscMPIInt size; 848 PetscErrorCode ierr; 849 850 PetscFunctionBegin; 851 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 852 if (!((PetscObject)A)->type_name) { 853 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr); 854 if (size == 1) { 855 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr); 856 } else { 857 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr); 858 } 859 } 860 if (!A->preallocated && A->ops->setup) { 861 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 862 ierr = (*A->ops->setup)(A);CHKERRQ(ierr); 863 } 864 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 865 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 866 A->preallocated = PETSC_TRUE; 867 PetscFunctionReturn(0); 868 } 869 870 #if defined(PETSC_HAVE_SAWS) 871 #include <petscviewersaws.h> 872 #endif 873 874 /*@C 875 MatViewFromOptions - View from Options 876 877 Collective on Mat 878 879 Input Parameters: 880 + A - the Mat context 881 . obj - Optional object 882 - name - command line option 883 884 Level: intermediate 885 .seealso: Mat, MatView, PetscObjectViewFromOptions(), MatCreate() 886 @*/ 887 PetscErrorCode MatViewFromOptions(Mat A,PetscObject obj,const char name[]) 888 { 889 PetscErrorCode ierr; 890 891 PetscFunctionBegin; 892 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 893 ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr); 894 PetscFunctionReturn(0); 895 } 896 897 /*@C 898 MatView - Visualizes a matrix object. 899 900 Collective on Mat 901 902 Input Parameters: 903 + mat - the matrix 904 - viewer - visualization context 905 906 Notes: 907 The available visualization contexts include 908 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 909 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 910 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 911 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 912 913 The user can open alternative visualization contexts with 914 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 915 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 916 specified file; corresponding input uses MatLoad() 917 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 918 an X window display 919 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 920 Currently only the sequential dense and AIJ 921 matrix types support the Socket viewer. 922 923 The user can call PetscViewerPushFormat() to specify the output 924 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 925 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 926 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 927 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 928 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 929 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 930 format common among all matrix types 931 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 932 format (which is in many cases the same as the default) 933 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 934 size and structure (not the matrix entries) 935 - PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 936 the matrix structure 937 938 Options Database Keys: 939 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 940 . -mat_view ::ascii_info_detail - Prints more detailed info 941 . -mat_view - Prints matrix in ASCII format 942 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 943 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 944 . -display <name> - Sets display name (default is host) 945 . -draw_pause <sec> - Sets number of seconds to pause after display 946 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 947 . -viewer_socket_machine <machine> - 948 . -viewer_socket_port <port> - 949 . -mat_view binary - save matrix to file in binary format 950 - -viewer_binary_filename <name> - 951 Level: beginner 952 953 Notes: 954 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 955 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 956 957 See the manual page for MatLoad() for the exact format of the binary file when the binary 958 viewer is used. 959 960 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 961 viewer is used. 962 963 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 964 and then use the following mouse functions. 965 + left mouse: zoom in 966 . middle mouse: zoom out 967 - right mouse: continue with the simulation 968 969 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 970 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 971 @*/ 972 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 973 { 974 PetscErrorCode ierr; 975 PetscInt rows,cols,rbs,cbs; 976 PetscBool iascii,ibinary,isstring; 977 PetscViewerFormat format; 978 PetscMPIInt size; 979 #if defined(PETSC_HAVE_SAWS) 980 PetscBool issaws; 981 #endif 982 983 PetscFunctionBegin; 984 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 985 PetscValidType(mat,1); 986 if (!viewer) { 987 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr); 988 } 989 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 990 PetscCheckSameComm(mat,1,viewer,2); 991 MatCheckPreallocated(mat,1); 992 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 993 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 994 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 995 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 996 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 997 if (ibinary) { 998 PetscBool mpiio; 999 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr); 1000 if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag"); 1001 } 1002 1003 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1004 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1005 if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 1006 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed"); 1007 } 1008 1009 #if defined(PETSC_HAVE_SAWS) 1010 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 1011 #endif 1012 if (iascii) { 1013 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1014 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr); 1015 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1016 MatNullSpace nullsp,transnullsp; 1017 1018 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1019 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1020 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 1021 if (rbs != 1 || cbs != 1) { 1022 if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs=%D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);} 1023 else {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);} 1024 } else { 1025 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr); 1026 } 1027 if (mat->factortype) { 1028 MatSolverType solver; 1029 ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr); 1030 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr); 1031 } 1032 if (mat->ops->getinfo) { 1033 MatInfo info; 1034 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 1035 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr); 1036 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls=%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr); 1037 } 1038 ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr); 1039 ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr); 1040 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);} 1041 if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached transposed null space\n");CHKERRQ(ierr);} 1042 ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr); 1043 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached near null space\n");CHKERRQ(ierr);} 1044 } 1045 #if defined(PETSC_HAVE_SAWS) 1046 } else if (issaws) { 1047 PetscMPIInt rank; 1048 1049 ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr); 1050 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1051 if (!((PetscObject)mat)->amsmem && !rank) { 1052 ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr); 1053 } 1054 #endif 1055 } else if (isstring) { 1056 const char *type; 1057 ierr = MatGetType(mat,&type);CHKERRQ(ierr); 1058 ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr); 1059 if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);} 1060 } 1061 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1062 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1063 ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr); 1064 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1065 } else if (mat->ops->view) { 1066 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1067 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 1068 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1069 } 1070 if (iascii) { 1071 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1072 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1073 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1074 } 1075 } 1076 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1077 PetscFunctionReturn(0); 1078 } 1079 1080 #if defined(PETSC_USE_DEBUG) 1081 #include <../src/sys/totalview/tv_data_display.h> 1082 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1083 { 1084 TV_add_row("Local rows", "int", &mat->rmap->n); 1085 TV_add_row("Local columns", "int", &mat->cmap->n); 1086 TV_add_row("Global rows", "int", &mat->rmap->N); 1087 TV_add_row("Global columns", "int", &mat->cmap->N); 1088 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1089 return TV_format_OK; 1090 } 1091 #endif 1092 1093 /*@C 1094 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1095 with MatView(). The matrix format is determined from the options database. 1096 Generates a parallel MPI matrix if the communicator has more than one 1097 processor. The default matrix type is AIJ. 1098 1099 Collective on PetscViewer 1100 1101 Input Parameters: 1102 + newmat - the newly loaded matrix, this needs to have been created with MatCreate() 1103 or some related function before a call to MatLoad() 1104 - viewer - binary/HDF5 file viewer 1105 1106 Options Database Keys: 1107 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1108 block size 1109 . -matload_block_size <bs> 1110 1111 Level: beginner 1112 1113 Notes: 1114 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1115 Mat before calling this routine if you wish to set it from the options database. 1116 1117 MatLoad() automatically loads into the options database any options 1118 given in the file filename.info where filename is the name of the file 1119 that was passed to the PetscViewerBinaryOpen(). The options in the info 1120 file will be ignored if you use the -viewer_binary_skip_info option. 1121 1122 If the type or size of newmat is not set before a call to MatLoad, PETSc 1123 sets the default matrix type AIJ and sets the local and global sizes. 1124 If type and/or size is already set, then the same are used. 1125 1126 In parallel, each processor can load a subset of rows (or the 1127 entire matrix). This routine is especially useful when a large 1128 matrix is stored on disk and only part of it is desired on each 1129 processor. For example, a parallel solver may access only some of 1130 the rows from each processor. The algorithm used here reads 1131 relatively small blocks of data rather than reading the entire 1132 matrix and then subsetting it. 1133 1134 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5. 1135 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(), 1136 or the sequence like 1137 $ PetscViewer v; 1138 $ PetscViewerCreate(PETSC_COMM_WORLD,&v); 1139 $ PetscViewerSetType(v,PETSCVIEWERBINARY); 1140 $ PetscViewerSetFromOptions(v); 1141 $ PetscViewerFileSetMode(v,FILE_MODE_READ); 1142 $ PetscViewerFileSetName(v,"datafile"); 1143 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option 1144 $ -viewer_type {binary,hdf5} 1145 1146 See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach, 1147 and src/mat/examples/tutorials/ex10.c with the second approach. 1148 1149 Notes about the PETSc binary format: 1150 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks 1151 is read onto rank 0 and then shipped to its destination rank, one after another. 1152 Multiple objects, both matrices and vectors, can be stored within the same file. 1153 Their PetscObject name is ignored; they are loaded in the order of their storage. 1154 1155 Most users should not need to know the details of the binary storage 1156 format, since MatLoad() and MatView() completely hide these details. 1157 But for anyone who's interested, the standard binary matrix storage 1158 format is 1159 1160 $ PetscInt MAT_FILE_CLASSID 1161 $ PetscInt number of rows 1162 $ PetscInt number of columns 1163 $ PetscInt total number of nonzeros 1164 $ PetscInt *number nonzeros in each row 1165 $ PetscInt *column indices of all nonzeros (starting index is zero) 1166 $ PetscScalar *values of all nonzeros 1167 1168 PETSc automatically does the byte swapping for 1169 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1170 linux, Windows and the paragon; thus if you write your own binary 1171 read/write routines you have to swap the bytes; see PetscBinaryRead() 1172 and PetscBinaryWrite() to see how this may be done. 1173 1174 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1175 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used. 1176 Each processor's chunk is loaded independently by its owning rank. 1177 Multiple objects, both matrices and vectors, can be stored within the same file. 1178 They are looked up by their PetscObject name. 1179 1180 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1181 by default the same structure and naming of the AIJ arrays and column count 1182 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1183 $ save example.mat A b -v7.3 1184 can be directly read by this routine (see Reference 1 for details). 1185 Note that depending on your MATLAB version, this format might be a default, 1186 otherwise you can set it as default in Preferences. 1187 1188 Unless -nocompression flag is used to save the file in MATLAB, 1189 PETSc must be configured with ZLIB package. 1190 1191 See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c 1192 1193 Current HDF5 (MAT-File) limitations: 1194 This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices. 1195 1196 Corresponding MatView() is not yet implemented. 1197 1198 The loaded matrix is actually a transpose of the original one in MATLAB, 1199 unless you push PETSC_VIEWER_HDF5_MAT format (see examples above). 1200 With this format, matrix is automatically transposed by PETSc, 1201 unless the matrix is marked as SPD or symmetric 1202 (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC). 1203 1204 References: 1205 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1206 1207 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad() 1208 1209 @*/ 1210 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer) 1211 { 1212 PetscErrorCode ierr; 1213 PetscBool flg; 1214 1215 PetscFunctionBegin; 1216 PetscValidHeaderSpecific(newmat,MAT_CLASSID,1); 1217 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1218 1219 if (!((PetscObject)newmat)->type_name) { 1220 ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 1221 } 1222 1223 flg = PETSC_FALSE; 1224 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr); 1225 if (flg) { 1226 ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 1227 ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); 1228 } 1229 flg = PETSC_FALSE; 1230 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr); 1231 if (flg) { 1232 ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 1233 } 1234 1235 if (!newmat->ops->load) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type %s",((PetscObject)newmat)->type_name); 1236 ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1237 ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr); 1238 ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1239 PetscFunctionReturn(0); 1240 } 1241 1242 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1243 { 1244 PetscErrorCode ierr; 1245 Mat_Redundant *redund = *redundant; 1246 PetscInt i; 1247 1248 PetscFunctionBegin; 1249 if (redund){ 1250 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1251 ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr); 1252 ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr); 1253 ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr); 1254 } else { 1255 ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr); 1256 ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr); 1257 ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr); 1258 for (i=0; i<redund->nrecvs; i++) { 1259 ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr); 1260 ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr); 1261 } 1262 ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr); 1263 } 1264 1265 if (redund->subcomm) { 1266 ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr); 1267 } 1268 ierr = PetscFree(redund);CHKERRQ(ierr); 1269 } 1270 PetscFunctionReturn(0); 1271 } 1272 1273 /*@ 1274 MatDestroy - Frees space taken by a matrix. 1275 1276 Collective on Mat 1277 1278 Input Parameter: 1279 . A - the matrix 1280 1281 Level: beginner 1282 1283 @*/ 1284 PetscErrorCode MatDestroy(Mat *A) 1285 { 1286 PetscErrorCode ierr; 1287 1288 PetscFunctionBegin; 1289 if (!*A) PetscFunctionReturn(0); 1290 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1291 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1292 1293 /* if memory was published with SAWs then destroy it */ 1294 ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr); 1295 if ((*A)->ops->destroy) { 1296 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr); 1297 } 1298 1299 ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr); 1300 ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr); 1301 ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr); 1302 ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr); 1303 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr); 1304 ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr); 1305 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr); 1306 ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr); 1307 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr); 1308 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr); 1309 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr); 1310 PetscFunctionReturn(0); 1311 } 1312 1313 /*@C 1314 MatSetValues - Inserts or adds a block of values into a matrix. 1315 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1316 MUST be called after all calls to MatSetValues() have been completed. 1317 1318 Not Collective 1319 1320 Input Parameters: 1321 + mat - the matrix 1322 . v - a logically two-dimensional array of values 1323 . m, idxm - the number of rows and their global indices 1324 . n, idxn - the number of columns and their global indices 1325 - addv - either ADD_VALUES or INSERT_VALUES, where 1326 ADD_VALUES adds values to any existing entries, and 1327 INSERT_VALUES replaces existing entries with new values 1328 1329 Notes: 1330 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1331 MatSetUp() before using this routine 1332 1333 By default the values, v, are row-oriented. See MatSetOption() for other options. 1334 1335 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1336 options cannot be mixed without intervening calls to the assembly 1337 routines. 1338 1339 MatSetValues() uses 0-based row and column numbers in Fortran 1340 as well as in C. 1341 1342 Negative indices may be passed in idxm and idxn, these rows and columns are 1343 simply ignored. This allows easily inserting element stiffness matrices 1344 with homogeneous Dirchlet boundary conditions that you don't want represented 1345 in the matrix. 1346 1347 Efficiency Alert: 1348 The routine MatSetValuesBlocked() may offer much better efficiency 1349 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1350 1351 Level: beginner 1352 1353 Developer Notes: 1354 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1355 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1356 1357 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1358 InsertMode, INSERT_VALUES, ADD_VALUES 1359 @*/ 1360 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1361 { 1362 PetscErrorCode ierr; 1363 #if defined(PETSC_USE_DEBUG) 1364 PetscInt i,j; 1365 #endif 1366 1367 PetscFunctionBeginHot; 1368 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1369 PetscValidType(mat,1); 1370 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1371 PetscValidIntPointer(idxm,3); 1372 PetscValidIntPointer(idxn,5); 1373 MatCheckPreallocated(mat,1); 1374 1375 if (mat->insertmode == NOT_SET_VALUES) { 1376 mat->insertmode = addv; 1377 } 1378 #if defined(PETSC_USE_DEBUG) 1379 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1380 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1381 if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1382 1383 for (i=0; i<m; i++) { 1384 for (j=0; j<n; j++) { 1385 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1386 #if defined(PETSC_USE_COMPLEX) 1387 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]); 1388 #else 1389 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]); 1390 #endif 1391 } 1392 } 1393 #endif 1394 1395 if (mat->assembled) { 1396 mat->was_assembled = PETSC_TRUE; 1397 mat->assembled = PETSC_FALSE; 1398 } 1399 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1400 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1401 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1402 PetscFunctionReturn(0); 1403 } 1404 1405 1406 /*@ 1407 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1408 values into a matrix 1409 1410 Not Collective 1411 1412 Input Parameters: 1413 + mat - the matrix 1414 . row - the (block) row to set 1415 - v - a logically two-dimensional array of values 1416 1417 Notes: 1418 By the values, v, are column-oriented (for the block version) and sorted 1419 1420 All the nonzeros in the row must be provided 1421 1422 The matrix must have previously had its column indices set 1423 1424 The row must belong to this process 1425 1426 Level: intermediate 1427 1428 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1429 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1430 @*/ 1431 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1432 { 1433 PetscErrorCode ierr; 1434 PetscInt globalrow; 1435 1436 PetscFunctionBegin; 1437 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1438 PetscValidType(mat,1); 1439 PetscValidScalarPointer(v,2); 1440 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr); 1441 ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr); 1442 PetscFunctionReturn(0); 1443 } 1444 1445 /*@ 1446 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1447 values into a matrix 1448 1449 Not Collective 1450 1451 Input Parameters: 1452 + mat - the matrix 1453 . row - the (block) row to set 1454 - 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 1455 1456 Notes: 1457 The values, v, are column-oriented for the block version. 1458 1459 All the nonzeros in the row must be provided 1460 1461 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1462 1463 The row must belong to this process 1464 1465 Level: advanced 1466 1467 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1468 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1469 @*/ 1470 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1471 { 1472 PetscErrorCode ierr; 1473 1474 PetscFunctionBeginHot; 1475 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1476 PetscValidType(mat,1); 1477 MatCheckPreallocated(mat,1); 1478 PetscValidScalarPointer(v,2); 1479 #if defined(PETSC_USE_DEBUG) 1480 if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1481 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1482 #endif 1483 mat->insertmode = INSERT_VALUES; 1484 1485 if (mat->assembled) { 1486 mat->was_assembled = PETSC_TRUE; 1487 mat->assembled = PETSC_FALSE; 1488 } 1489 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1490 if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1491 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr); 1492 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1493 PetscFunctionReturn(0); 1494 } 1495 1496 /*@ 1497 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1498 Using structured grid indexing 1499 1500 Not Collective 1501 1502 Input Parameters: 1503 + mat - the matrix 1504 . m - number of rows being entered 1505 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1506 . n - number of columns being entered 1507 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1508 . v - a logically two-dimensional array of values 1509 - addv - either ADD_VALUES or INSERT_VALUES, where 1510 ADD_VALUES adds values to any existing entries, and 1511 INSERT_VALUES replaces existing entries with new values 1512 1513 Notes: 1514 By default the values, v, are row-oriented. See MatSetOption() for other options. 1515 1516 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1517 options cannot be mixed without intervening calls to the assembly 1518 routines. 1519 1520 The grid coordinates are across the entire grid, not just the local portion 1521 1522 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1523 as well as in C. 1524 1525 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1526 1527 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1528 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1529 1530 The columns and rows in the stencil passed in MUST be contained within the 1531 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1532 if you create a DMDA with an overlap of one grid level and on a particular process its first 1533 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1534 first i index you can use in your column and row indices in MatSetStencil() is 5. 1535 1536 In Fortran idxm and idxn should be declared as 1537 $ MatStencil idxm(4,m),idxn(4,n) 1538 and the values inserted using 1539 $ idxm(MatStencil_i,1) = i 1540 $ idxm(MatStencil_j,1) = j 1541 $ idxm(MatStencil_k,1) = k 1542 $ idxm(MatStencil_c,1) = c 1543 etc 1544 1545 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1546 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1547 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1548 DM_BOUNDARY_PERIODIC boundary type. 1549 1550 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 1551 a single value per point) you can skip filling those indices. 1552 1553 Inspired by the structured grid interface to the HYPRE package 1554 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1555 1556 Efficiency Alert: 1557 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1558 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1559 1560 Level: beginner 1561 1562 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1563 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1564 @*/ 1565 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1566 { 1567 PetscErrorCode ierr; 1568 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1569 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1570 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1571 1572 PetscFunctionBegin; 1573 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1574 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1575 PetscValidType(mat,1); 1576 PetscValidIntPointer(idxm,3); 1577 PetscValidIntPointer(idxn,5); 1578 1579 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1580 jdxm = buf; jdxn = buf+m; 1581 } else { 1582 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1583 jdxm = bufm; jdxn = bufn; 1584 } 1585 for (i=0; i<m; i++) { 1586 for (j=0; j<3-sdim; j++) dxm++; 1587 tmp = *dxm++ - starts[0]; 1588 for (j=0; j<dim-1; j++) { 1589 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1590 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1591 } 1592 if (mat->stencil.noc) dxm++; 1593 jdxm[i] = tmp; 1594 } 1595 for (i=0; i<n; i++) { 1596 for (j=0; j<3-sdim; j++) dxn++; 1597 tmp = *dxn++ - starts[0]; 1598 for (j=0; j<dim-1; j++) { 1599 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1600 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1601 } 1602 if (mat->stencil.noc) dxn++; 1603 jdxn[i] = tmp; 1604 } 1605 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1606 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1607 PetscFunctionReturn(0); 1608 } 1609 1610 /*@ 1611 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1612 Using structured grid indexing 1613 1614 Not Collective 1615 1616 Input Parameters: 1617 + mat - the matrix 1618 . m - number of rows being entered 1619 . idxm - grid coordinates for matrix rows being entered 1620 . n - number of columns being entered 1621 . idxn - grid coordinates for matrix columns being entered 1622 . v - a logically two-dimensional array of values 1623 - addv - either ADD_VALUES or INSERT_VALUES, where 1624 ADD_VALUES adds values to any existing entries, and 1625 INSERT_VALUES replaces existing entries with new values 1626 1627 Notes: 1628 By default the values, v, are row-oriented and unsorted. 1629 See MatSetOption() for other options. 1630 1631 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1632 options cannot be mixed without intervening calls to the assembly 1633 routines. 1634 1635 The grid coordinates are across the entire grid, not just the local portion 1636 1637 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1638 as well as in C. 1639 1640 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1641 1642 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1643 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1644 1645 The columns and rows in the stencil passed in MUST be contained within the 1646 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1647 if you create a DMDA with an overlap of one grid level and on a particular process its first 1648 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1649 first i index you can use in your column and row indices in MatSetStencil() is 5. 1650 1651 In Fortran idxm and idxn should be declared as 1652 $ MatStencil idxm(4,m),idxn(4,n) 1653 and the values inserted using 1654 $ idxm(MatStencil_i,1) = i 1655 $ idxm(MatStencil_j,1) = j 1656 $ idxm(MatStencil_k,1) = k 1657 etc 1658 1659 Negative indices may be passed in idxm and idxn, these rows and columns are 1660 simply ignored. This allows easily inserting element stiffness matrices 1661 with homogeneous Dirchlet boundary conditions that you don't want represented 1662 in the matrix. 1663 1664 Inspired by the structured grid interface to the HYPRE package 1665 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1666 1667 Level: beginner 1668 1669 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1670 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1671 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1672 @*/ 1673 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1674 { 1675 PetscErrorCode ierr; 1676 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1677 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1678 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1679 1680 PetscFunctionBegin; 1681 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1682 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1683 PetscValidType(mat,1); 1684 PetscValidIntPointer(idxm,3); 1685 PetscValidIntPointer(idxn,5); 1686 PetscValidScalarPointer(v,6); 1687 1688 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1689 jdxm = buf; jdxn = buf+m; 1690 } else { 1691 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1692 jdxm = bufm; jdxn = bufn; 1693 } 1694 for (i=0; i<m; i++) { 1695 for (j=0; j<3-sdim; j++) dxm++; 1696 tmp = *dxm++ - starts[0]; 1697 for (j=0; j<sdim-1; j++) { 1698 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1699 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1700 } 1701 dxm++; 1702 jdxm[i] = tmp; 1703 } 1704 for (i=0; i<n; i++) { 1705 for (j=0; j<3-sdim; j++) dxn++; 1706 tmp = *dxn++ - starts[0]; 1707 for (j=0; j<sdim-1; j++) { 1708 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1709 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1710 } 1711 dxn++; 1712 jdxn[i] = tmp; 1713 } 1714 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1715 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1716 PetscFunctionReturn(0); 1717 } 1718 1719 /*@ 1720 MatSetStencil - Sets the grid information for setting values into a matrix via 1721 MatSetValuesStencil() 1722 1723 Not Collective 1724 1725 Input Parameters: 1726 + mat - the matrix 1727 . dim - dimension of the grid 1, 2, or 3 1728 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1729 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1730 - dof - number of degrees of freedom per node 1731 1732 1733 Inspired by the structured grid interface to the HYPRE package 1734 (www.llnl.gov/CASC/hyper) 1735 1736 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1737 user. 1738 1739 Level: beginner 1740 1741 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1742 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1743 @*/ 1744 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1745 { 1746 PetscInt i; 1747 1748 PetscFunctionBegin; 1749 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1750 PetscValidIntPointer(dims,3); 1751 PetscValidIntPointer(starts,4); 1752 1753 mat->stencil.dim = dim + (dof > 1); 1754 for (i=0; i<dim; i++) { 1755 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1756 mat->stencil.starts[i] = starts[dim-i-1]; 1757 } 1758 mat->stencil.dims[dim] = dof; 1759 mat->stencil.starts[dim] = 0; 1760 mat->stencil.noc = (PetscBool)(dof == 1); 1761 PetscFunctionReturn(0); 1762 } 1763 1764 /*@C 1765 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1766 1767 Not Collective 1768 1769 Input Parameters: 1770 + mat - the matrix 1771 . v - a logically two-dimensional array of values 1772 . m, idxm - the number of block rows and their global block indices 1773 . n, idxn - the number of block columns and their global block indices 1774 - addv - either ADD_VALUES or INSERT_VALUES, where 1775 ADD_VALUES adds values to any existing entries, and 1776 INSERT_VALUES replaces existing entries with new values 1777 1778 Notes: 1779 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1780 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1781 1782 The m and n count the NUMBER of blocks in the row direction and column direction, 1783 NOT the total number of rows/columns; for example, if the block size is 2 and 1784 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1785 The values in idxm would be 1 2; that is the first index for each block divided by 1786 the block size. 1787 1788 Note that you must call MatSetBlockSize() when constructing this matrix (before 1789 preallocating it). 1790 1791 By default the values, v, are row-oriented, so the layout of 1792 v is the same as for MatSetValues(). See MatSetOption() for other options. 1793 1794 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1795 options cannot be mixed without intervening calls to the assembly 1796 routines. 1797 1798 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1799 as well as in C. 1800 1801 Negative indices may be passed in idxm and idxn, these rows and columns are 1802 simply ignored. This allows easily inserting element stiffness matrices 1803 with homogeneous Dirchlet boundary conditions that you don't want represented 1804 in the matrix. 1805 1806 Each time an entry is set within a sparse matrix via MatSetValues(), 1807 internal searching must be done to determine where to place the 1808 data in the matrix storage space. By instead inserting blocks of 1809 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1810 reduced. 1811 1812 Example: 1813 $ Suppose m=n=2 and block size(bs) = 2 The array is 1814 $ 1815 $ 1 2 | 3 4 1816 $ 5 6 | 7 8 1817 $ - - - | - - - 1818 $ 9 10 | 11 12 1819 $ 13 14 | 15 16 1820 $ 1821 $ v[] should be passed in like 1822 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1823 $ 1824 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1825 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1826 1827 Level: intermediate 1828 1829 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1830 @*/ 1831 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1832 { 1833 PetscErrorCode ierr; 1834 1835 PetscFunctionBeginHot; 1836 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1837 PetscValidType(mat,1); 1838 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1839 PetscValidIntPointer(idxm,3); 1840 PetscValidIntPointer(idxn,5); 1841 PetscValidScalarPointer(v,6); 1842 MatCheckPreallocated(mat,1); 1843 if (mat->insertmode == NOT_SET_VALUES) { 1844 mat->insertmode = addv; 1845 } 1846 #if defined(PETSC_USE_DEBUG) 1847 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1848 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1849 if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1850 #endif 1851 1852 if (mat->assembled) { 1853 mat->was_assembled = PETSC_TRUE; 1854 mat->assembled = PETSC_FALSE; 1855 } 1856 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1857 if (mat->ops->setvaluesblocked) { 1858 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1859 } else { 1860 PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn; 1861 PetscInt i,j,bs,cbs; 1862 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr); 1863 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1864 iidxm = buf; iidxn = buf + m*bs; 1865 } else { 1866 ierr = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr); 1867 iidxm = bufr; iidxn = bufc; 1868 } 1869 for (i=0; i<m; i++) { 1870 for (j=0; j<bs; j++) { 1871 iidxm[i*bs+j] = bs*idxm[i] + j; 1872 } 1873 } 1874 for (i=0; i<n; i++) { 1875 for (j=0; j<cbs; j++) { 1876 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1877 } 1878 } 1879 ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr); 1880 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1881 } 1882 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1883 PetscFunctionReturn(0); 1884 } 1885 1886 /*@ 1887 MatGetValues - Gets a block of values from a matrix. 1888 1889 Not Collective; currently only returns a local block 1890 1891 Input Parameters: 1892 + mat - the matrix 1893 . v - a logically two-dimensional array for storing the values 1894 . m, idxm - the number of rows and their global indices 1895 - n, idxn - the number of columns and their global indices 1896 1897 Notes: 1898 The user must allocate space (m*n PetscScalars) for the values, v. 1899 The values, v, are then returned in a row-oriented format, 1900 analogous to that used by default in MatSetValues(). 1901 1902 MatGetValues() uses 0-based row and column numbers in 1903 Fortran as well as in C. 1904 1905 MatGetValues() requires that the matrix has been assembled 1906 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1907 MatSetValues() and MatGetValues() CANNOT be made in succession 1908 without intermediate matrix assembly. 1909 1910 Negative row or column indices will be ignored and those locations in v[] will be 1911 left unchanged. 1912 1913 Level: advanced 1914 1915 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues() 1916 @*/ 1917 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1918 { 1919 PetscErrorCode ierr; 1920 1921 PetscFunctionBegin; 1922 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1923 PetscValidType(mat,1); 1924 if (!m || !n) PetscFunctionReturn(0); 1925 PetscValidIntPointer(idxm,3); 1926 PetscValidIntPointer(idxn,5); 1927 PetscValidScalarPointer(v,6); 1928 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1929 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1930 if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1931 MatCheckPreallocated(mat,1); 1932 1933 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1934 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 1935 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1936 PetscFunctionReturn(0); 1937 } 1938 1939 /*@ 1940 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 1941 the same size. Currently, this can only be called once and creates the given matrix. 1942 1943 Not Collective 1944 1945 Input Parameters: 1946 + mat - the matrix 1947 . nb - the number of blocks 1948 . bs - the number of rows (and columns) in each block 1949 . rows - a concatenation of the rows for each block 1950 - v - a concatenation of logically two-dimensional arrays of values 1951 1952 Notes: 1953 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 1954 1955 Level: advanced 1956 1957 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1958 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1959 @*/ 1960 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 1961 { 1962 PetscErrorCode ierr; 1963 1964 PetscFunctionBegin; 1965 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1966 PetscValidType(mat,1); 1967 PetscValidScalarPointer(rows,4); 1968 PetscValidScalarPointer(v,5); 1969 #if defined(PETSC_USE_DEBUG) 1970 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1971 #endif 1972 1973 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1974 if (mat->ops->setvaluesbatch) { 1975 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr); 1976 } else { 1977 PetscInt b; 1978 for (b = 0; b < nb; ++b) { 1979 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr); 1980 } 1981 } 1982 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1983 PetscFunctionReturn(0); 1984 } 1985 1986 /*@ 1987 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 1988 the routine MatSetValuesLocal() to allow users to insert matrix entries 1989 using a local (per-processor) numbering. 1990 1991 Not Collective 1992 1993 Input Parameters: 1994 + x - the matrix 1995 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 1996 - cmapping - column mapping 1997 1998 Level: intermediate 1999 2000 2001 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal() 2002 @*/ 2003 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2004 { 2005 PetscErrorCode ierr; 2006 2007 PetscFunctionBegin; 2008 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2009 PetscValidType(x,1); 2010 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2011 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2012 2013 if (x->ops->setlocaltoglobalmapping) { 2014 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr); 2015 } else { 2016 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr); 2017 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr); 2018 } 2019 PetscFunctionReturn(0); 2020 } 2021 2022 2023 /*@ 2024 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2025 2026 Not Collective 2027 2028 Input Parameters: 2029 . A - the matrix 2030 2031 Output Parameters: 2032 + rmapping - row mapping 2033 - cmapping - column mapping 2034 2035 Level: advanced 2036 2037 2038 .seealso: MatSetValuesLocal() 2039 @*/ 2040 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2041 { 2042 PetscFunctionBegin; 2043 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2044 PetscValidType(A,1); 2045 if (rmapping) PetscValidPointer(rmapping,2); 2046 if (cmapping) PetscValidPointer(cmapping,3); 2047 if (rmapping) *rmapping = A->rmap->mapping; 2048 if (cmapping) *cmapping = A->cmap->mapping; 2049 PetscFunctionReturn(0); 2050 } 2051 2052 /*@ 2053 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2054 2055 Not Collective 2056 2057 Input Parameters: 2058 . A - the matrix 2059 2060 Output Parameters: 2061 + rmap - row layout 2062 - cmap - column layout 2063 2064 Level: advanced 2065 2066 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping() 2067 @*/ 2068 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2069 { 2070 PetscFunctionBegin; 2071 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2072 PetscValidType(A,1); 2073 if (rmap) PetscValidPointer(rmap,2); 2074 if (cmap) PetscValidPointer(cmap,3); 2075 if (rmap) *rmap = A->rmap; 2076 if (cmap) *cmap = A->cmap; 2077 PetscFunctionReturn(0); 2078 } 2079 2080 /*@C 2081 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2082 using a local ordering of the nodes. 2083 2084 Not Collective 2085 2086 Input Parameters: 2087 + mat - the matrix 2088 . nrow, irow - number of rows and their local indices 2089 . ncol, icol - number of columns and their local indices 2090 . y - a logically two-dimensional array of values 2091 - addv - either INSERT_VALUES or ADD_VALUES, where 2092 ADD_VALUES adds values to any existing entries, and 2093 INSERT_VALUES replaces existing entries with new values 2094 2095 Notes: 2096 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2097 MatSetUp() before using this routine 2098 2099 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2100 2101 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2102 options cannot be mixed without intervening calls to the assembly 2103 routines. 2104 2105 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2106 MUST be called after all calls to MatSetValuesLocal() have been completed. 2107 2108 Level: intermediate 2109 2110 Developer Notes: 2111 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2112 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2113 2114 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 2115 MatSetValueLocal() 2116 @*/ 2117 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2118 { 2119 PetscErrorCode ierr; 2120 2121 PetscFunctionBeginHot; 2122 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2123 PetscValidType(mat,1); 2124 MatCheckPreallocated(mat,1); 2125 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2126 PetscValidIntPointer(irow,3); 2127 PetscValidIntPointer(icol,5); 2128 if (mat->insertmode == NOT_SET_VALUES) { 2129 mat->insertmode = addv; 2130 } 2131 #if defined(PETSC_USE_DEBUG) 2132 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2133 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2134 if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2135 #endif 2136 2137 if (mat->assembled) { 2138 mat->was_assembled = PETSC_TRUE; 2139 mat->assembled = PETSC_FALSE; 2140 } 2141 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2142 if (mat->ops->setvalueslocal) { 2143 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2144 } else { 2145 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2146 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2147 irowm = buf; icolm = buf+nrow; 2148 } else { 2149 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2150 irowm = bufr; icolm = bufc; 2151 } 2152 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2153 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2154 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2155 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2156 } 2157 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2158 PetscFunctionReturn(0); 2159 } 2160 2161 /*@C 2162 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2163 using a local ordering of the nodes a block at a time. 2164 2165 Not Collective 2166 2167 Input Parameters: 2168 + x - the matrix 2169 . nrow, irow - number of rows and their local indices 2170 . ncol, icol - number of columns and their local indices 2171 . y - a logically two-dimensional array of values 2172 - addv - either INSERT_VALUES or ADD_VALUES, where 2173 ADD_VALUES adds values to any existing entries, and 2174 INSERT_VALUES replaces existing entries with new values 2175 2176 Notes: 2177 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2178 MatSetUp() before using this routine 2179 2180 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2181 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2182 2183 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2184 options cannot be mixed without intervening calls to the assembly 2185 routines. 2186 2187 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2188 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2189 2190 Level: intermediate 2191 2192 Developer Notes: 2193 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2194 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2195 2196 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(), 2197 MatSetValuesLocal(), MatSetValuesBlocked() 2198 @*/ 2199 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2200 { 2201 PetscErrorCode ierr; 2202 2203 PetscFunctionBeginHot; 2204 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2205 PetscValidType(mat,1); 2206 MatCheckPreallocated(mat,1); 2207 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2208 PetscValidIntPointer(irow,3); 2209 PetscValidIntPointer(icol,5); 2210 PetscValidScalarPointer(y,6); 2211 if (mat->insertmode == NOT_SET_VALUES) { 2212 mat->insertmode = addv; 2213 } 2214 #if defined(PETSC_USE_DEBUG) 2215 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2216 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2217 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); 2218 #endif 2219 2220 if (mat->assembled) { 2221 mat->was_assembled = PETSC_TRUE; 2222 mat->assembled = PETSC_FALSE; 2223 } 2224 #if defined(PETSC_USE_DEBUG) 2225 /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2226 if (mat->rmap->mapping) { 2227 PetscInt irbs, rbs; 2228 ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr); 2229 ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr); 2230 if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs); 2231 } 2232 if (mat->cmap->mapping) { 2233 PetscInt icbs, cbs; 2234 ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr); 2235 ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr); 2236 if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs); 2237 } 2238 #endif 2239 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2240 if (mat->ops->setvaluesblockedlocal) { 2241 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2242 } else { 2243 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2244 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2245 irowm = buf; icolm = buf + nrow; 2246 } else { 2247 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2248 irowm = bufr; icolm = bufc; 2249 } 2250 ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2251 ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2252 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2253 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2254 } 2255 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2256 PetscFunctionReturn(0); 2257 } 2258 2259 /*@ 2260 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2261 2262 Collective on Mat 2263 2264 Input Parameters: 2265 + mat - the matrix 2266 - x - the vector to be multiplied 2267 2268 Output Parameters: 2269 . y - the result 2270 2271 Notes: 2272 The vectors x and y cannot be the same. I.e., one cannot 2273 call MatMult(A,y,y). 2274 2275 Level: developer 2276 2277 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2278 @*/ 2279 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2280 { 2281 PetscErrorCode ierr; 2282 2283 PetscFunctionBegin; 2284 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2285 PetscValidType(mat,1); 2286 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2287 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2288 2289 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2290 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2291 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2292 MatCheckPreallocated(mat,1); 2293 2294 if (!mat->ops->multdiagonalblock) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2295 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr); 2296 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2297 PetscFunctionReturn(0); 2298 } 2299 2300 /* --------------------------------------------------------*/ 2301 /*@ 2302 MatMult - Computes the matrix-vector product, y = Ax. 2303 2304 Neighbor-wise Collective on Mat 2305 2306 Input Parameters: 2307 + mat - the matrix 2308 - x - the vector to be multiplied 2309 2310 Output Parameters: 2311 . y - the result 2312 2313 Notes: 2314 The vectors x and y cannot be the same. I.e., one cannot 2315 call MatMult(A,y,y). 2316 2317 Level: beginner 2318 2319 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2320 @*/ 2321 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2322 { 2323 PetscErrorCode ierr; 2324 2325 PetscFunctionBegin; 2326 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2327 PetscValidType(mat,1); 2328 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2329 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2330 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2331 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2332 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2333 #if !defined(PETSC_HAVE_CONSTRAINTS) 2334 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); 2335 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); 2336 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); 2337 #endif 2338 ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr); 2339 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2340 MatCheckPreallocated(mat,1); 2341 2342 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2343 if (!mat->ops->mult) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply defined",((PetscObject)mat)->type_name); 2344 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2345 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2346 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2347 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2348 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2349 PetscFunctionReturn(0); 2350 } 2351 2352 /*@ 2353 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2354 2355 Neighbor-wise Collective on Mat 2356 2357 Input Parameters: 2358 + mat - the matrix 2359 - x - the vector to be multiplied 2360 2361 Output Parameters: 2362 . y - the result 2363 2364 Notes: 2365 The vectors x and y cannot be the same. I.e., one cannot 2366 call MatMultTranspose(A,y,y). 2367 2368 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2369 use MatMultHermitianTranspose() 2370 2371 Level: beginner 2372 2373 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2374 @*/ 2375 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2376 { 2377 PetscErrorCode ierr; 2378 2379 PetscFunctionBegin; 2380 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2381 PetscValidType(mat,1); 2382 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2383 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2384 2385 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2386 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2387 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2388 #if !defined(PETSC_HAVE_CONSTRAINTS) 2389 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); 2390 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); 2391 #endif 2392 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2393 MatCheckPreallocated(mat,1); 2394 2395 if (!mat->ops->multtranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a multiply transpose defined",((PetscObject)mat)->type_name); 2396 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2397 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2398 ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr); 2399 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2400 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2401 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2402 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2403 PetscFunctionReturn(0); 2404 } 2405 2406 /*@ 2407 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2408 2409 Neighbor-wise Collective on Mat 2410 2411 Input Parameters: 2412 + mat - the matrix 2413 - x - the vector to be multilplied 2414 2415 Output Parameters: 2416 . y - the result 2417 2418 Notes: 2419 The vectors x and y cannot be the same. I.e., one cannot 2420 call MatMultHermitianTranspose(A,y,y). 2421 2422 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2423 2424 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2425 2426 Level: beginner 2427 2428 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2429 @*/ 2430 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2431 { 2432 PetscErrorCode ierr; 2433 Vec w; 2434 2435 PetscFunctionBegin; 2436 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2437 PetscValidType(mat,1); 2438 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2439 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2440 2441 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2442 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2443 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2444 #if !defined(PETSC_HAVE_CONSTRAINTS) 2445 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); 2446 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); 2447 #endif 2448 MatCheckPreallocated(mat,1); 2449 2450 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2451 if (mat->ops->multhermitiantranspose) { 2452 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2453 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr); 2454 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2455 } else { 2456 ierr = VecDuplicate(x,&w);CHKERRQ(ierr); 2457 ierr = VecCopy(x,w);CHKERRQ(ierr); 2458 ierr = VecConjugate(w);CHKERRQ(ierr); 2459 ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr); 2460 ierr = VecDestroy(&w);CHKERRQ(ierr); 2461 ierr = VecConjugate(y);CHKERRQ(ierr); 2462 } 2463 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2464 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2465 PetscFunctionReturn(0); 2466 } 2467 2468 /*@ 2469 MatMultAdd - Computes v3 = v2 + A * v1. 2470 2471 Neighbor-wise Collective on Mat 2472 2473 Input Parameters: 2474 + mat - the matrix 2475 - v1, v2 - the vectors 2476 2477 Output Parameters: 2478 . v3 - the result 2479 2480 Notes: 2481 The vectors v1 and v3 cannot be the same. I.e., one cannot 2482 call MatMultAdd(A,v1,v2,v1). 2483 2484 Level: beginner 2485 2486 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2487 @*/ 2488 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2489 { 2490 PetscErrorCode ierr; 2491 2492 PetscFunctionBegin; 2493 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2494 PetscValidType(mat,1); 2495 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2496 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2497 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2498 2499 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2500 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2501 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); 2502 /* 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); 2503 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); */ 2504 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); 2505 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); 2506 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2507 MatCheckPreallocated(mat,1); 2508 2509 if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type %s",((PetscObject)mat)->type_name); 2510 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2511 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2512 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2513 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2514 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2515 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2516 PetscFunctionReturn(0); 2517 } 2518 2519 /*@ 2520 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2521 2522 Neighbor-wise Collective on Mat 2523 2524 Input Parameters: 2525 + mat - the matrix 2526 - v1, v2 - the vectors 2527 2528 Output Parameters: 2529 . v3 - the result 2530 2531 Notes: 2532 The vectors v1 and v3 cannot be the same. I.e., one cannot 2533 call MatMultTransposeAdd(A,v1,v2,v1). 2534 2535 Level: beginner 2536 2537 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2538 @*/ 2539 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2540 { 2541 PetscErrorCode ierr; 2542 2543 PetscFunctionBegin; 2544 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2545 PetscValidType(mat,1); 2546 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2547 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2548 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2549 2550 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2551 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2552 if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2553 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2554 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); 2555 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); 2556 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); 2557 MatCheckPreallocated(mat,1); 2558 2559 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2560 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2561 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2562 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2563 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2564 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2565 PetscFunctionReturn(0); 2566 } 2567 2568 /*@ 2569 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2570 2571 Neighbor-wise Collective on Mat 2572 2573 Input Parameters: 2574 + mat - the matrix 2575 - v1, v2 - the vectors 2576 2577 Output Parameters: 2578 . v3 - the result 2579 2580 Notes: 2581 The vectors v1 and v3 cannot be the same. I.e., one cannot 2582 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2583 2584 Level: beginner 2585 2586 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2587 @*/ 2588 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2589 { 2590 PetscErrorCode ierr; 2591 2592 PetscFunctionBegin; 2593 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2594 PetscValidType(mat,1); 2595 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2596 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2597 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2598 2599 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2600 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2601 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2602 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); 2603 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); 2604 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); 2605 MatCheckPreallocated(mat,1); 2606 2607 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2608 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2609 if (mat->ops->multhermitiantransposeadd) { 2610 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2611 } else { 2612 Vec w,z; 2613 ierr = VecDuplicate(v1,&w);CHKERRQ(ierr); 2614 ierr = VecCopy(v1,w);CHKERRQ(ierr); 2615 ierr = VecConjugate(w);CHKERRQ(ierr); 2616 ierr = VecDuplicate(v3,&z);CHKERRQ(ierr); 2617 ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr); 2618 ierr = VecDestroy(&w);CHKERRQ(ierr); 2619 ierr = VecConjugate(z);CHKERRQ(ierr); 2620 if (v2 != v3) { 2621 ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr); 2622 } else { 2623 ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr); 2624 } 2625 ierr = VecDestroy(&z);CHKERRQ(ierr); 2626 } 2627 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2628 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2629 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2630 PetscFunctionReturn(0); 2631 } 2632 2633 /*@ 2634 MatMultConstrained - The inner multiplication routine for a 2635 constrained matrix P^T A P. 2636 2637 Neighbor-wise Collective on Mat 2638 2639 Input Parameters: 2640 + mat - the matrix 2641 - x - the vector to be multilplied 2642 2643 Output Parameters: 2644 . y - the result 2645 2646 Notes: 2647 The vectors x and y cannot be the same. I.e., one cannot 2648 call MatMult(A,y,y). 2649 2650 Level: beginner 2651 2652 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2653 @*/ 2654 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y) 2655 { 2656 PetscErrorCode ierr; 2657 2658 PetscFunctionBegin; 2659 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2660 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2661 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2662 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2663 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2664 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2665 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); 2666 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); 2667 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); 2668 2669 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2670 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2671 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr); 2672 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2673 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2674 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2675 PetscFunctionReturn(0); 2676 } 2677 2678 /*@ 2679 MatMultTransposeConstrained - The inner multiplication routine for a 2680 constrained matrix P^T A^T P. 2681 2682 Neighbor-wise Collective on Mat 2683 2684 Input Parameters: 2685 + mat - the matrix 2686 - x - the vector to be multilplied 2687 2688 Output Parameters: 2689 . y - the result 2690 2691 Notes: 2692 The vectors x and y cannot be the same. I.e., one cannot 2693 call MatMult(A,y,y). 2694 2695 Level: beginner 2696 2697 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2698 @*/ 2699 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 2700 { 2701 PetscErrorCode ierr; 2702 2703 PetscFunctionBegin; 2704 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2705 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2706 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2707 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2708 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2709 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2710 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); 2711 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); 2712 2713 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2714 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 2715 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2716 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2717 PetscFunctionReturn(0); 2718 } 2719 2720 /*@C 2721 MatGetFactorType - gets the type of factorization it is 2722 2723 Not Collective 2724 2725 Input Parameters: 2726 . mat - the matrix 2727 2728 Output Parameters: 2729 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2730 2731 Level: intermediate 2732 2733 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType() 2734 @*/ 2735 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2736 { 2737 PetscFunctionBegin; 2738 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2739 PetscValidType(mat,1); 2740 PetscValidPointer(t,2); 2741 *t = mat->factortype; 2742 PetscFunctionReturn(0); 2743 } 2744 2745 /*@C 2746 MatSetFactorType - sets the type of factorization it is 2747 2748 Logically Collective on Mat 2749 2750 Input Parameters: 2751 + mat - the matrix 2752 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2753 2754 Level: intermediate 2755 2756 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType() 2757 @*/ 2758 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2759 { 2760 PetscFunctionBegin; 2761 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2762 PetscValidType(mat,1); 2763 mat->factortype = t; 2764 PetscFunctionReturn(0); 2765 } 2766 2767 /* ------------------------------------------------------------*/ 2768 /*@C 2769 MatGetInfo - Returns information about matrix storage (number of 2770 nonzeros, memory, etc.). 2771 2772 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2773 2774 Input Parameters: 2775 . mat - the matrix 2776 2777 Output Parameters: 2778 + flag - flag indicating the type of parameters to be returned 2779 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2780 MAT_GLOBAL_SUM - sum over all processors) 2781 - info - matrix information context 2782 2783 Notes: 2784 The MatInfo context contains a variety of matrix data, including 2785 number of nonzeros allocated and used, number of mallocs during 2786 matrix assembly, etc. Additional information for factored matrices 2787 is provided (such as the fill ratio, number of mallocs during 2788 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2789 when using the runtime options 2790 $ -info -mat_view ::ascii_info 2791 2792 Example for C/C++ Users: 2793 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2794 data within the MatInfo context. For example, 2795 .vb 2796 MatInfo info; 2797 Mat A; 2798 double mal, nz_a, nz_u; 2799 2800 MatGetInfo(A,MAT_LOCAL,&info); 2801 mal = info.mallocs; 2802 nz_a = info.nz_allocated; 2803 .ve 2804 2805 Example for Fortran Users: 2806 Fortran users should declare info as a double precision 2807 array of dimension MAT_INFO_SIZE, and then extract the parameters 2808 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2809 a complete list of parameter names. 2810 .vb 2811 double precision info(MAT_INFO_SIZE) 2812 double precision mal, nz_a 2813 Mat A 2814 integer ierr 2815 2816 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2817 mal = info(MAT_INFO_MALLOCS) 2818 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2819 .ve 2820 2821 Level: intermediate 2822 2823 Developer Note: fortran interface is not autogenerated as the f90 2824 interface defintion cannot be generated correctly [due to MatInfo] 2825 2826 .seealso: MatStashGetInfo() 2827 2828 @*/ 2829 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2830 { 2831 PetscErrorCode ierr; 2832 2833 PetscFunctionBegin; 2834 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2835 PetscValidType(mat,1); 2836 PetscValidPointer(info,3); 2837 if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2838 MatCheckPreallocated(mat,1); 2839 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 2840 PetscFunctionReturn(0); 2841 } 2842 2843 /* 2844 This is used by external packages where it is not easy to get the info from the actual 2845 matrix factorization. 2846 */ 2847 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2848 { 2849 PetscErrorCode ierr; 2850 2851 PetscFunctionBegin; 2852 ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr); 2853 PetscFunctionReturn(0); 2854 } 2855 2856 /* ----------------------------------------------------------*/ 2857 2858 /*@C 2859 MatLUFactor - Performs in-place LU factorization of matrix. 2860 2861 Collective on Mat 2862 2863 Input Parameters: 2864 + mat - the matrix 2865 . row - row permutation 2866 . col - column permutation 2867 - info - options for factorization, includes 2868 $ fill - expected fill as ratio of original fill. 2869 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2870 $ Run with the option -info to determine an optimal value to use 2871 2872 Notes: 2873 Most users should employ the simplified KSP interface for linear solvers 2874 instead of working directly with matrix algebra routines such as this. 2875 See, e.g., KSPCreate(). 2876 2877 This changes the state of the matrix to a factored matrix; it cannot be used 2878 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2879 2880 Level: developer 2881 2882 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 2883 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 2884 2885 Developer Note: fortran interface is not autogenerated as the f90 2886 interface defintion cannot be generated correctly [due to MatFactorInfo] 2887 2888 @*/ 2889 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2890 { 2891 PetscErrorCode ierr; 2892 MatFactorInfo tinfo; 2893 2894 PetscFunctionBegin; 2895 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2896 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2897 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2898 if (info) PetscValidPointer(info,4); 2899 PetscValidType(mat,1); 2900 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2901 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2902 if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2903 MatCheckPreallocated(mat,1); 2904 if (!info) { 2905 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2906 info = &tinfo; 2907 } 2908 2909 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2910 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 2911 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2912 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2913 PetscFunctionReturn(0); 2914 } 2915 2916 /*@C 2917 MatILUFactor - Performs in-place ILU factorization of matrix. 2918 2919 Collective on Mat 2920 2921 Input Parameters: 2922 + mat - the matrix 2923 . row - row permutation 2924 . col - column permutation 2925 - info - structure containing 2926 $ levels - number of levels of fill. 2927 $ expected fill - as ratio of original fill. 2928 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2929 missing diagonal entries) 2930 2931 Notes: 2932 Probably really in-place only when level of fill is zero, otherwise allocates 2933 new space to store factored matrix and deletes previous memory. 2934 2935 Most users should employ the simplified KSP interface for linear solvers 2936 instead of working directly with matrix algebra routines such as this. 2937 See, e.g., KSPCreate(). 2938 2939 Level: developer 2940 2941 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 2942 2943 Developer Note: fortran interface is not autogenerated as the f90 2944 interface defintion cannot be generated correctly [due to MatFactorInfo] 2945 2946 @*/ 2947 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2948 { 2949 PetscErrorCode ierr; 2950 2951 PetscFunctionBegin; 2952 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2953 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2954 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2955 PetscValidPointer(info,4); 2956 PetscValidType(mat,1); 2957 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 2958 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2959 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2960 if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2961 MatCheckPreallocated(mat,1); 2962 2963 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2964 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 2965 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2966 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2967 PetscFunctionReturn(0); 2968 } 2969 2970 /*@C 2971 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 2972 Call this routine before calling MatLUFactorNumeric(). 2973 2974 Collective on Mat 2975 2976 Input Parameters: 2977 + fact - the factor matrix obtained with MatGetFactor() 2978 . mat - the matrix 2979 . row, col - row and column permutations 2980 - info - options for factorization, includes 2981 $ fill - expected fill as ratio of original fill. 2982 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2983 $ Run with the option -info to determine an optimal value to use 2984 2985 2986 Notes: 2987 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 2988 2989 Most users should employ the simplified KSP interface for linear solvers 2990 instead of working directly with matrix algebra routines such as this. 2991 See, e.g., KSPCreate(). 2992 2993 Level: developer 2994 2995 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize() 2996 2997 Developer Note: fortran interface is not autogenerated as the f90 2998 interface defintion cannot be generated correctly [due to MatFactorInfo] 2999 3000 @*/ 3001 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3002 { 3003 PetscErrorCode ierr; 3004 MatFactorInfo tinfo; 3005 3006 PetscFunctionBegin; 3007 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3008 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3009 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3010 if (info) PetscValidPointer(info,4); 3011 PetscValidType(mat,1); 3012 PetscValidPointer(fact,5); 3013 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3014 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3015 if (!(fact)->ops->lufactorsymbolic) { 3016 MatSolverType spackage; 3017 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3018 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage); 3019 } 3020 MatCheckPreallocated(mat,2); 3021 if (!info) { 3022 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3023 info = &tinfo; 3024 } 3025 3026 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3027 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 3028 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3029 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3030 PetscFunctionReturn(0); 3031 } 3032 3033 /*@C 3034 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3035 Call this routine after first calling MatLUFactorSymbolic(). 3036 3037 Collective on Mat 3038 3039 Input Parameters: 3040 + fact - the factor matrix obtained with MatGetFactor() 3041 . mat - the matrix 3042 - info - options for factorization 3043 3044 Notes: 3045 See MatLUFactor() for in-place factorization. See 3046 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3047 3048 Most users should employ the simplified KSP interface for linear solvers 3049 instead of working directly with matrix algebra routines such as this. 3050 See, e.g., KSPCreate(). 3051 3052 Level: developer 3053 3054 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 3055 3056 Developer Note: fortran interface is not autogenerated as the f90 3057 interface defintion cannot be generated correctly [due to MatFactorInfo] 3058 3059 @*/ 3060 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3061 { 3062 MatFactorInfo tinfo; 3063 PetscErrorCode ierr; 3064 3065 PetscFunctionBegin; 3066 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3067 PetscValidType(mat,1); 3068 PetscValidPointer(fact,2); 3069 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3070 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3071 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); 3072 3073 if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3074 MatCheckPreallocated(mat,2); 3075 if (!info) { 3076 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3077 info = &tinfo; 3078 } 3079 3080 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3081 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr); 3082 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3083 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3084 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3085 PetscFunctionReturn(0); 3086 } 3087 3088 /*@C 3089 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3090 symmetric matrix. 3091 3092 Collective on Mat 3093 3094 Input Parameters: 3095 + mat - the matrix 3096 . perm - row and column permutations 3097 - f - expected fill as ratio of original fill 3098 3099 Notes: 3100 See MatLUFactor() for the nonsymmetric case. See also 3101 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3102 3103 Most users should employ the simplified KSP interface for linear solvers 3104 instead of working directly with matrix algebra routines such as this. 3105 See, e.g., KSPCreate(). 3106 3107 Level: developer 3108 3109 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 3110 MatGetOrdering() 3111 3112 Developer Note: fortran interface is not autogenerated as the f90 3113 interface defintion cannot be generated correctly [due to MatFactorInfo] 3114 3115 @*/ 3116 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3117 { 3118 PetscErrorCode ierr; 3119 MatFactorInfo tinfo; 3120 3121 PetscFunctionBegin; 3122 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3123 PetscValidType(mat,1); 3124 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3125 if (info) PetscValidPointer(info,3); 3126 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3127 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3128 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3129 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); 3130 MatCheckPreallocated(mat,1); 3131 if (!info) { 3132 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3133 info = &tinfo; 3134 } 3135 3136 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3137 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr); 3138 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3139 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3140 PetscFunctionReturn(0); 3141 } 3142 3143 /*@C 3144 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3145 of a symmetric matrix. 3146 3147 Collective on Mat 3148 3149 Input Parameters: 3150 + fact - the factor matrix obtained with MatGetFactor() 3151 . mat - the matrix 3152 . perm - row and column permutations 3153 - info - options for factorization, includes 3154 $ fill - expected fill as ratio of original fill. 3155 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3156 $ Run with the option -info to determine an optimal value to use 3157 3158 Notes: 3159 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3160 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3161 3162 Most users should employ the simplified KSP interface for linear solvers 3163 instead of working directly with matrix algebra routines such as this. 3164 See, e.g., KSPCreate(). 3165 3166 Level: developer 3167 3168 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 3169 MatGetOrdering() 3170 3171 Developer Note: fortran interface is not autogenerated as the f90 3172 interface defintion cannot be generated correctly [due to MatFactorInfo] 3173 3174 @*/ 3175 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3176 { 3177 PetscErrorCode ierr; 3178 MatFactorInfo tinfo; 3179 3180 PetscFunctionBegin; 3181 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3182 PetscValidType(mat,1); 3183 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3184 if (info) PetscValidPointer(info,3); 3185 PetscValidPointer(fact,4); 3186 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3187 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3188 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3189 if (!(fact)->ops->choleskyfactorsymbolic) { 3190 MatSolverType spackage; 3191 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3192 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage); 3193 } 3194 MatCheckPreallocated(mat,2); 3195 if (!info) { 3196 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3197 info = &tinfo; 3198 } 3199 3200 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3201 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 3202 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3203 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3204 PetscFunctionReturn(0); 3205 } 3206 3207 /*@C 3208 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3209 of a symmetric matrix. Call this routine after first calling 3210 MatCholeskyFactorSymbolic(). 3211 3212 Collective on Mat 3213 3214 Input Parameters: 3215 + fact - the factor matrix obtained with MatGetFactor() 3216 . mat - the initial matrix 3217 . info - options for factorization 3218 - fact - the symbolic factor of mat 3219 3220 3221 Notes: 3222 Most users should employ the simplified KSP interface for linear solvers 3223 instead of working directly with matrix algebra routines such as this. 3224 See, e.g., KSPCreate(). 3225 3226 Level: developer 3227 3228 .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 3229 3230 Developer Note: fortran interface is not autogenerated as the f90 3231 interface defintion cannot be generated correctly [due to MatFactorInfo] 3232 3233 @*/ 3234 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3235 { 3236 MatFactorInfo tinfo; 3237 PetscErrorCode ierr; 3238 3239 PetscFunctionBegin; 3240 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3241 PetscValidType(mat,1); 3242 PetscValidPointer(fact,2); 3243 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3244 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3245 if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3246 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); 3247 MatCheckPreallocated(mat,2); 3248 if (!info) { 3249 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 3250 info = &tinfo; 3251 } 3252 3253 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3254 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr); 3255 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3256 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3257 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3258 PetscFunctionReturn(0); 3259 } 3260 3261 /* ----------------------------------------------------------------*/ 3262 /*@ 3263 MatSolve - Solves A x = b, given a factored matrix. 3264 3265 Neighbor-wise Collective on Mat 3266 3267 Input Parameters: 3268 + mat - the factored matrix 3269 - b - the right-hand-side vector 3270 3271 Output Parameter: 3272 . x - the result vector 3273 3274 Notes: 3275 The vectors b and x cannot be the same. I.e., one cannot 3276 call MatSolve(A,x,x). 3277 3278 Notes: 3279 Most users should employ the simplified KSP interface for linear solvers 3280 instead of working directly with matrix algebra routines such as this. 3281 See, e.g., KSPCreate(). 3282 3283 Level: developer 3284 3285 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3286 @*/ 3287 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3288 { 3289 PetscErrorCode ierr; 3290 3291 PetscFunctionBegin; 3292 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3293 PetscValidType(mat,1); 3294 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3295 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3296 PetscCheckSameComm(mat,1,b,2); 3297 PetscCheckSameComm(mat,1,x,3); 3298 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3299 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); 3300 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); 3301 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); 3302 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3303 MatCheckPreallocated(mat,1); 3304 3305 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3306 if (mat->factorerrortype) { 3307 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3308 ierr = VecSetInf(x);CHKERRQ(ierr); 3309 } else { 3310 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3311 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 3312 } 3313 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3314 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3315 PetscFunctionReturn(0); 3316 } 3317 3318 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X,PetscBool trans) 3319 { 3320 PetscErrorCode ierr; 3321 Vec b,x; 3322 PetscInt m,N,i; 3323 PetscScalar *bb,*xx; 3324 3325 PetscFunctionBegin; 3326 ierr = MatDenseGetArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr); 3327 ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr); 3328 ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr); /* number local rows */ 3329 ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr); /* total columns in dense matrix */ 3330 ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr); 3331 for (i=0; i<N; i++) { 3332 ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr); 3333 ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr); 3334 if (trans) { 3335 ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr); 3336 } else { 3337 ierr = MatSolve(A,b,x);CHKERRQ(ierr); 3338 } 3339 ierr = VecResetArray(x);CHKERRQ(ierr); 3340 ierr = VecResetArray(b);CHKERRQ(ierr); 3341 } 3342 ierr = VecDestroy(&b);CHKERRQ(ierr); 3343 ierr = VecDestroy(&x);CHKERRQ(ierr); 3344 ierr = MatDenseRestoreArrayRead(B,(const PetscScalar**)&bb);CHKERRQ(ierr); 3345 ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr); 3346 PetscFunctionReturn(0); 3347 } 3348 3349 /*@ 3350 MatMatSolve - Solves A X = B, given a factored matrix. 3351 3352 Neighbor-wise Collective on Mat 3353 3354 Input Parameters: 3355 + A - the factored matrix 3356 - B - the right-hand-side matrix MATDENSE (or sparse -- when using MUMPS) 3357 3358 Output Parameter: 3359 . X - the result matrix (dense matrix) 3360 3361 Notes: 3362 If B is a MATDENSE matrix then one can call MatMatSolve(A,B,B); 3363 otherwise, B and X cannot be the same. 3364 3365 Notes: 3366 Most users should usually employ the simplified KSP interface for linear solvers 3367 instead of working directly with matrix algebra routines such as this. 3368 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3369 at a time. 3370 3371 Level: developer 3372 3373 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3374 @*/ 3375 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3376 { 3377 PetscErrorCode ierr; 3378 3379 PetscFunctionBegin; 3380 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3381 PetscValidType(A,1); 3382 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3383 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3384 PetscCheckSameComm(A,1,B,2); 3385 PetscCheckSameComm(A,1,X,3); 3386 if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N); 3387 if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N); 3388 if (X->cmap->N != B->cmap->N) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3389 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3390 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3391 MatCheckPreallocated(A,1); 3392 3393 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3394 if (!A->ops->matsolve) { 3395 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3396 ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr); 3397 } else { 3398 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr); 3399 } 3400 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3401 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3402 PetscFunctionReturn(0); 3403 } 3404 3405 /*@ 3406 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3407 3408 Neighbor-wise Collective on Mat 3409 3410 Input Parameters: 3411 + A - the factored matrix 3412 - B - the right-hand-side matrix (dense matrix) 3413 3414 Output Parameter: 3415 . X - the result matrix (dense matrix) 3416 3417 Notes: 3418 The matrices B and X cannot be the same. I.e., one cannot 3419 call MatMatSolveTranspose(A,X,X). 3420 3421 Notes: 3422 Most users should usually employ the simplified KSP interface for linear solvers 3423 instead of working directly with matrix algebra routines such as this. 3424 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3425 at a time. 3426 3427 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3428 3429 Level: developer 3430 3431 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor() 3432 @*/ 3433 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3434 { 3435 PetscErrorCode ierr; 3436 3437 PetscFunctionBegin; 3438 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3439 PetscValidType(A,1); 3440 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3441 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3442 PetscCheckSameComm(A,1,B,2); 3443 PetscCheckSameComm(A,1,X,3); 3444 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3445 if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N); 3446 if (A->rmap->N != B->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat B: global dim %D %D",A->rmap->N,B->rmap->N); 3447 if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat A,Mat B: local dim %D %D",A->rmap->n,B->rmap->n); 3448 if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix"); 3449 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3450 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3451 MatCheckPreallocated(A,1); 3452 3453 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3454 if (!A->ops->matsolvetranspose) { 3455 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3456 ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr); 3457 } else { 3458 ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr); 3459 } 3460 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3461 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3462 PetscFunctionReturn(0); 3463 } 3464 3465 /*@ 3466 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3467 3468 Neighbor-wise Collective on Mat 3469 3470 Input Parameters: 3471 + A - the factored matrix 3472 - Bt - the transpose of right-hand-side matrix 3473 3474 Output Parameter: 3475 . X - the result matrix (dense matrix) 3476 3477 Notes: 3478 Most users should usually employ the simplified KSP interface for linear solvers 3479 instead of working directly with matrix algebra routines such as this. 3480 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3481 at a time. 3482 3483 For MUMPS, it only supports centralized sparse compressed column format on the host processor for right hand side matrix. User must create B^T in sparse compressed row format on the host processor and call MatMatTransposeSolve() to implement MUMPS' MatMatSolve(). 3484 3485 Level: developer 3486 3487 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3488 @*/ 3489 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3490 { 3491 PetscErrorCode ierr; 3492 3493 PetscFunctionBegin; 3494 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3495 PetscValidType(A,1); 3496 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3497 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3498 PetscCheckSameComm(A,1,Bt,2); 3499 PetscCheckSameComm(A,1,X,3); 3500 3501 if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3502 if (A->cmap->N != X->rmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat X: global dim %D %D",A->cmap->N,X->rmap->N); 3503 if (A->rmap->N != Bt->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Mat A,Mat Bt: global dim %D %D",A->rmap->N,Bt->cmap->N); 3504 if (X->cmap->N < Bt->rmap->N) SETERRQ(PetscObjectComm((PetscObject)X),PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as row number of the rhs matrix"); 3505 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3506 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3507 MatCheckPreallocated(A,1); 3508 3509 if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3510 ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3511 ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr); 3512 ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3513 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3514 PetscFunctionReturn(0); 3515 } 3516 3517 /*@ 3518 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3519 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3520 3521 Neighbor-wise Collective on Mat 3522 3523 Input Parameters: 3524 + mat - the factored matrix 3525 - b - the right-hand-side vector 3526 3527 Output Parameter: 3528 . x - the result vector 3529 3530 Notes: 3531 MatSolve() should be used for most applications, as it performs 3532 a forward solve followed by a backward solve. 3533 3534 The vectors b and x cannot be the same, i.e., one cannot 3535 call MatForwardSolve(A,x,x). 3536 3537 For matrix in seqsbaij format with block size larger than 1, 3538 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3539 MatForwardSolve() solves U^T*D y = b, and 3540 MatBackwardSolve() solves U x = y. 3541 Thus they do not provide a symmetric preconditioner. 3542 3543 Most users should employ the simplified KSP interface for linear solvers 3544 instead of working directly with matrix algebra routines such as this. 3545 See, e.g., KSPCreate(). 3546 3547 Level: developer 3548 3549 .seealso: MatSolve(), MatBackwardSolve() 3550 @*/ 3551 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3552 { 3553 PetscErrorCode ierr; 3554 3555 PetscFunctionBegin; 3556 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3557 PetscValidType(mat,1); 3558 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3559 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3560 PetscCheckSameComm(mat,1,b,2); 3561 PetscCheckSameComm(mat,1,x,3); 3562 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3563 if (mat->cmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->cmap->N,x->map->N); 3564 if (mat->rmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->rmap->N,b->map->N); 3565 if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n); 3566 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3567 MatCheckPreallocated(mat,1); 3568 3569 if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3570 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3571 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 3572 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3573 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3574 PetscFunctionReturn(0); 3575 } 3576 3577 /*@ 3578 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3579 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3580 3581 Neighbor-wise Collective on Mat 3582 3583 Input Parameters: 3584 + mat - the factored matrix 3585 - b - the right-hand-side vector 3586 3587 Output Parameter: 3588 . x - the result vector 3589 3590 Notes: 3591 MatSolve() should be used for most applications, as it performs 3592 a forward solve followed by a backward solve. 3593 3594 The vectors b and x cannot be the same. I.e., one cannot 3595 call MatBackwardSolve(A,x,x). 3596 3597 For matrix in seqsbaij format with block size larger than 1, 3598 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3599 MatForwardSolve() solves U^T*D y = b, and 3600 MatBackwardSolve() solves U x = y. 3601 Thus they do not provide a symmetric preconditioner. 3602 3603 Most users should employ the simplified KSP interface for linear solvers 3604 instead of working directly with matrix algebra routines such as this. 3605 See, e.g., KSPCreate(). 3606 3607 Level: developer 3608 3609 .seealso: MatSolve(), MatForwardSolve() 3610 @*/ 3611 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3612 { 3613 PetscErrorCode ierr; 3614 3615 PetscFunctionBegin; 3616 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3617 PetscValidType(mat,1); 3618 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3619 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3620 PetscCheckSameComm(mat,1,b,2); 3621 PetscCheckSameComm(mat,1,x,3); 3622 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3623 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); 3624 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); 3625 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); 3626 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3627 MatCheckPreallocated(mat,1); 3628 3629 if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3630 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3631 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 3632 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3633 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3634 PetscFunctionReturn(0); 3635 } 3636 3637 /*@ 3638 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3639 3640 Neighbor-wise Collective on Mat 3641 3642 Input Parameters: 3643 + mat - the factored matrix 3644 . b - the right-hand-side vector 3645 - y - the vector to be added to 3646 3647 Output Parameter: 3648 . x - the result vector 3649 3650 Notes: 3651 The vectors b and x cannot be the same. I.e., one cannot 3652 call MatSolveAdd(A,x,y,x). 3653 3654 Most users should employ the simplified KSP interface for linear solvers 3655 instead of working directly with matrix algebra routines such as this. 3656 See, e.g., KSPCreate(). 3657 3658 Level: developer 3659 3660 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3661 @*/ 3662 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3663 { 3664 PetscScalar one = 1.0; 3665 Vec tmp; 3666 PetscErrorCode ierr; 3667 3668 PetscFunctionBegin; 3669 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3670 PetscValidType(mat,1); 3671 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3672 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3673 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3674 PetscCheckSameComm(mat,1,b,2); 3675 PetscCheckSameComm(mat,1,y,2); 3676 PetscCheckSameComm(mat,1,x,3); 3677 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3678 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); 3679 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); 3680 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); 3681 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); 3682 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); 3683 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3684 MatCheckPreallocated(mat,1); 3685 3686 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3687 if (mat->factorerrortype) { 3688 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3689 ierr = VecSetInf(x);CHKERRQ(ierr); 3690 } else if (mat->ops->solveadd) { 3691 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 3692 } else { 3693 /* do the solve then the add manually */ 3694 if (x != y) { 3695 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3696 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3697 } else { 3698 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3699 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3700 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3701 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3702 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3703 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3704 } 3705 } 3706 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3707 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3708 PetscFunctionReturn(0); 3709 } 3710 3711 /*@ 3712 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3713 3714 Neighbor-wise Collective on Mat 3715 3716 Input Parameters: 3717 + mat - the factored matrix 3718 - b - the right-hand-side vector 3719 3720 Output Parameter: 3721 . x - the result vector 3722 3723 Notes: 3724 The vectors b and x cannot be the same. I.e., one cannot 3725 call MatSolveTranspose(A,x,x). 3726 3727 Most users should employ the simplified KSP interface for linear solvers 3728 instead of working directly with matrix algebra routines such as this. 3729 See, e.g., KSPCreate(). 3730 3731 Level: developer 3732 3733 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 3734 @*/ 3735 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3736 { 3737 PetscErrorCode ierr; 3738 3739 PetscFunctionBegin; 3740 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3741 PetscValidType(mat,1); 3742 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3743 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3744 PetscCheckSameComm(mat,1,b,2); 3745 PetscCheckSameComm(mat,1,x,3); 3746 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3747 if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N); 3748 if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N); 3749 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3750 MatCheckPreallocated(mat,1); 3751 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3752 if (mat->factorerrortype) { 3753 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3754 ierr = VecSetInf(x);CHKERRQ(ierr); 3755 } else { 3756 if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3757 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr); 3758 } 3759 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3760 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3761 PetscFunctionReturn(0); 3762 } 3763 3764 /*@ 3765 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3766 factored matrix. 3767 3768 Neighbor-wise Collective on Mat 3769 3770 Input Parameters: 3771 + mat - the factored matrix 3772 . b - the right-hand-side vector 3773 - y - the vector to be added to 3774 3775 Output Parameter: 3776 . x - the result vector 3777 3778 Notes: 3779 The vectors b and x cannot be the same. I.e., one cannot 3780 call MatSolveTransposeAdd(A,x,y,x). 3781 3782 Most users should employ the simplified KSP interface for linear solvers 3783 instead of working directly with matrix algebra routines such as this. 3784 See, e.g., KSPCreate(). 3785 3786 Level: developer 3787 3788 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 3789 @*/ 3790 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 3791 { 3792 PetscScalar one = 1.0; 3793 PetscErrorCode ierr; 3794 Vec tmp; 3795 3796 PetscFunctionBegin; 3797 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3798 PetscValidType(mat,1); 3799 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3800 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3801 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3802 PetscCheckSameComm(mat,1,b,2); 3803 PetscCheckSameComm(mat,1,y,3); 3804 PetscCheckSameComm(mat,1,x,4); 3805 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3806 if (mat->rmap->N != x->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N); 3807 if (mat->cmap->N != b->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: global dim %D %D",mat->cmap->N,b->map->N); 3808 if (mat->cmap->N != y->map->N) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N); 3809 if (x->map->n != y->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Vec x,Vec y: local dim %D %D",x->map->n,y->map->n); 3810 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3811 MatCheckPreallocated(mat,1); 3812 3813 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3814 if (mat->factorerrortype) { 3815 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3816 ierr = VecSetInf(x);CHKERRQ(ierr); 3817 } else if (mat->ops->solvetransposeadd){ 3818 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr); 3819 } else { 3820 /* do the solve then the add manually */ 3821 if (x != y) { 3822 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3823 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3824 } else { 3825 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3826 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3827 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3828 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3829 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3830 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3831 } 3832 } 3833 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3834 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3835 PetscFunctionReturn(0); 3836 } 3837 /* ----------------------------------------------------------------*/ 3838 3839 /*@ 3840 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3841 3842 Neighbor-wise Collective on Mat 3843 3844 Input Parameters: 3845 + mat - the matrix 3846 . b - the right hand side 3847 . omega - the relaxation factor 3848 . flag - flag indicating the type of SOR (see below) 3849 . shift - diagonal shift 3850 . its - the number of iterations 3851 - lits - the number of local iterations 3852 3853 Output Parameters: 3854 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 3855 3856 SOR Flags: 3857 + SOR_FORWARD_SWEEP - forward SOR 3858 . SOR_BACKWARD_SWEEP - backward SOR 3859 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 3860 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 3861 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 3862 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 3863 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 3864 upper/lower triangular part of matrix to 3865 vector (with omega) 3866 - SOR_ZERO_INITIAL_GUESS - zero initial guess 3867 3868 Notes: 3869 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 3870 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 3871 on each processor. 3872 3873 Application programmers will not generally use MatSOR() directly, 3874 but instead will employ the KSP/PC interface. 3875 3876 Notes: 3877 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 3878 3879 Notes for Advanced Users: 3880 The flags are implemented as bitwise inclusive or operations. 3881 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 3882 to specify a zero initial guess for SSOR. 3883 3884 Most users should employ the simplified KSP interface for linear solvers 3885 instead of working directly with matrix algebra routines such as this. 3886 See, e.g., KSPCreate(). 3887 3888 Vectors x and b CANNOT be the same 3889 3890 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 3891 3892 Level: developer 3893 3894 @*/ 3895 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 3896 { 3897 PetscErrorCode ierr; 3898 3899 PetscFunctionBegin; 3900 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3901 PetscValidType(mat,1); 3902 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3903 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 3904 PetscCheckSameComm(mat,1,b,2); 3905 PetscCheckSameComm(mat,1,x,8); 3906 if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3907 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3908 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3909 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); 3910 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); 3911 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); 3912 if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its); 3913 if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits); 3914 if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 3915 3916 MatCheckPreallocated(mat,1); 3917 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3918 ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 3919 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3920 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3921 PetscFunctionReturn(0); 3922 } 3923 3924 /* 3925 Default matrix copy routine. 3926 */ 3927 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 3928 { 3929 PetscErrorCode ierr; 3930 PetscInt i,rstart = 0,rend = 0,nz; 3931 const PetscInt *cwork; 3932 const PetscScalar *vwork; 3933 3934 PetscFunctionBegin; 3935 if (B->assembled) { 3936 ierr = MatZeroEntries(B);CHKERRQ(ierr); 3937 } 3938 if (str == SAME_NONZERO_PATTERN) { 3939 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 3940 for (i=rstart; i<rend; i++) { 3941 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3942 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 3943 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3944 } 3945 } else { 3946 ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr); 3947 } 3948 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3949 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3950 PetscFunctionReturn(0); 3951 } 3952 3953 /*@ 3954 MatCopy - Copies a matrix to another matrix. 3955 3956 Collective on Mat 3957 3958 Input Parameters: 3959 + A - the matrix 3960 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 3961 3962 Output Parameter: 3963 . B - where the copy is put 3964 3965 Notes: 3966 If you use SAME_NONZERO_PATTERN then the two matrices had better have the 3967 same nonzero pattern or the routine will crash. 3968 3969 MatCopy() copies the matrix entries of a matrix to another existing 3970 matrix (after first zeroing the second matrix). A related routine is 3971 MatConvert(), which first creates a new matrix and then copies the data. 3972 3973 Level: intermediate 3974 3975 .seealso: MatConvert(), MatDuplicate() 3976 3977 @*/ 3978 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 3979 { 3980 PetscErrorCode ierr; 3981 PetscInt i; 3982 3983 PetscFunctionBegin; 3984 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3985 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3986 PetscValidType(A,1); 3987 PetscValidType(B,2); 3988 PetscCheckSameComm(A,1,B,2); 3989 MatCheckPreallocated(B,2); 3990 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3991 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3992 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); 3993 MatCheckPreallocated(A,1); 3994 if (A == B) PetscFunctionReturn(0); 3995 3996 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 3997 if (A->ops->copy) { 3998 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 3999 } else { /* generic conversion */ 4000 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 4001 } 4002 4003 B->stencil.dim = A->stencil.dim; 4004 B->stencil.noc = A->stencil.noc; 4005 for (i=0; i<=A->stencil.dim; i++) { 4006 B->stencil.dims[i] = A->stencil.dims[i]; 4007 B->stencil.starts[i] = A->stencil.starts[i]; 4008 } 4009 4010 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4011 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4012 PetscFunctionReturn(0); 4013 } 4014 4015 /*@C 4016 MatConvert - Converts a matrix to another matrix, either of the same 4017 or different type. 4018 4019 Collective on Mat 4020 4021 Input Parameters: 4022 + mat - the matrix 4023 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4024 same type as the original matrix. 4025 - reuse - denotes if the destination matrix is to be created or reused. 4026 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 4027 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). 4028 4029 Output Parameter: 4030 . M - pointer to place new matrix 4031 4032 Notes: 4033 MatConvert() first creates a new matrix and then copies the data from 4034 the first matrix. A related routine is MatCopy(), which copies the matrix 4035 entries of one matrix to another already existing matrix context. 4036 4037 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4038 the MPI communicator of the generated matrix is always the same as the communicator 4039 of the input matrix. 4040 4041 Level: intermediate 4042 4043 .seealso: MatCopy(), MatDuplicate() 4044 @*/ 4045 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M) 4046 { 4047 PetscErrorCode ierr; 4048 PetscBool sametype,issame,flg,issymmetric,ishermitian; 4049 char convname[256],mtype[256]; 4050 Mat B; 4051 4052 PetscFunctionBegin; 4053 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4054 PetscValidType(mat,1); 4055 PetscValidPointer(M,3); 4056 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4057 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4058 MatCheckPreallocated(mat,1); 4059 4060 ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr); 4061 if (flg) newtype = mtype; 4062 4063 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 4064 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 4065 if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4066 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"); 4067 4068 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) { 4069 ierr = PetscInfo3(mat,"Early return for inplace %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr); 4070 PetscFunctionReturn(0); 4071 } 4072 4073 /* Cache Mat options because some converter use MatHeaderReplace */ 4074 issymmetric = mat->symmetric; 4075 ishermitian = mat->hermitian; 4076 4077 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4078 ierr = PetscInfo3(mat,"Calling duplicate for initial matrix %s %d %d\n",((PetscObject)mat)->type_name,sametype,issame);CHKERRQ(ierr); 4079 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4080 } else { 4081 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4082 const char *prefix[3] = {"seq","mpi",""}; 4083 PetscInt i; 4084 /* 4085 Order of precedence: 4086 0) See if newtype is a superclass of the current matrix. 4087 1) See if a specialized converter is known to the current matrix. 4088 2) See if a specialized converter is known to the desired matrix class. 4089 3) See if a good general converter is registered for the desired class 4090 (as of 6/27/03 only MATMPIADJ falls into this category). 4091 4) See if a good general converter is known for the current matrix. 4092 5) Use a really basic converter. 4093 */ 4094 4095 /* 0) See if newtype is a superclass of the current matrix. 4096 i.e mat is mpiaij and newtype is aij */ 4097 for (i=0; i<2; i++) { 4098 ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4099 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4100 ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr); 4101 ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr); 4102 if (flg) { 4103 if (reuse == MAT_INPLACE_MATRIX) { 4104 PetscFunctionReturn(0); 4105 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4106 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4107 PetscFunctionReturn(0); 4108 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4109 ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4110 PetscFunctionReturn(0); 4111 } 4112 } 4113 } 4114 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4115 for (i=0; i<3; i++) { 4116 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4117 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4118 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4119 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4120 ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr); 4121 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4122 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr); 4123 ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4124 if (conv) goto foundconv; 4125 } 4126 4127 /* 2) See if a specialized converter is known to the desired matrix class. */ 4128 ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 4129 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr); 4130 ierr = MatSetType(B,newtype);CHKERRQ(ierr); 4131 for (i=0; i<3; i++) { 4132 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4133 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4134 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4135 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4136 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4137 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4138 ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 4139 ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4140 if (conv) { 4141 ierr = MatDestroy(&B);CHKERRQ(ierr); 4142 goto foundconv; 4143 } 4144 } 4145 4146 /* 3) See if a good general converter is registered for the desired class */ 4147 conv = B->ops->convertfrom; 4148 ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4149 ierr = MatDestroy(&B);CHKERRQ(ierr); 4150 if (conv) goto foundconv; 4151 4152 /* 4) See if a good general converter is known for the current matrix */ 4153 if (mat->ops->convert) 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 SETERRQ4(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s for factorization type %s and matrix type %s. Perhaps you must ./configure with --download-%s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name,type); 4435 } else { 4436 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package for factorization type %s and matrix type %s.",MatFactorTypes[ftype],((PetscObject)mat)->type_name); 4437 } 4438 } 4439 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4440 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); 4441 4442 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4443 PetscFunctionReturn(0); 4444 } 4445 4446 /*@C 4447 MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type 4448 4449 Not Collective 4450 4451 Input Parameters: 4452 + mat - the matrix 4453 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4454 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4455 4456 Output Parameter: 4457 . flg - PETSC_TRUE if the factorization is available 4458 4459 Notes: 4460 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4461 such as pastix, superlu, mumps etc. 4462 4463 PETSc must have been ./configure to use the external solver, using the option --download-package 4464 4465 Level: intermediate 4466 4467 .seealso: MatCopy(), MatDuplicate(), MatGetFactor() 4468 @*/ 4469 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4470 { 4471 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4472 4473 PetscFunctionBegin; 4474 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4475 PetscValidType(mat,1); 4476 4477 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4478 MatCheckPreallocated(mat,1); 4479 4480 *flg = PETSC_FALSE; 4481 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4482 if (gconv) { 4483 *flg = PETSC_TRUE; 4484 } 4485 PetscFunctionReturn(0); 4486 } 4487 4488 #include <petscdmtypes.h> 4489 4490 /*@ 4491 MatDuplicate - Duplicates a matrix including the non-zero structure. 4492 4493 Collective on Mat 4494 4495 Input Parameters: 4496 + mat - the matrix 4497 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4498 See the manual page for MatDuplicateOption for an explanation of these options. 4499 4500 Output Parameter: 4501 . M - pointer to place new matrix 4502 4503 Level: intermediate 4504 4505 Notes: 4506 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4507 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. 4508 4509 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4510 @*/ 4511 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4512 { 4513 PetscErrorCode ierr; 4514 Mat B; 4515 PetscInt i; 4516 DM dm; 4517 void (*viewf)(void); 4518 4519 PetscFunctionBegin; 4520 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4521 PetscValidType(mat,1); 4522 PetscValidPointer(M,3); 4523 if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4524 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4525 MatCheckPreallocated(mat,1); 4526 4527 *M = 0; 4528 if (!mat->ops->duplicate) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for matrix type %s\n",((PetscObject)mat)->type_name); 4529 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4530 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4531 B = *M; 4532 4533 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr); 4534 if (viewf) { 4535 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr); 4536 } 4537 4538 B->stencil.dim = mat->stencil.dim; 4539 B->stencil.noc = mat->stencil.noc; 4540 for (i=0; i<=mat->stencil.dim; i++) { 4541 B->stencil.dims[i] = mat->stencil.dims[i]; 4542 B->stencil.starts[i] = mat->stencil.starts[i]; 4543 } 4544 4545 B->nooffproczerorows = mat->nooffproczerorows; 4546 B->nooffprocentries = mat->nooffprocentries; 4547 4548 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr); 4549 if (dm) { 4550 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 4551 } 4552 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4553 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4554 PetscFunctionReturn(0); 4555 } 4556 4557 /*@ 4558 MatGetDiagonal - Gets the diagonal of a matrix. 4559 4560 Logically Collective on Mat 4561 4562 Input Parameters: 4563 + mat - the matrix 4564 - v - the vector for storing the diagonal 4565 4566 Output Parameter: 4567 . v - the diagonal of the matrix 4568 4569 Level: intermediate 4570 4571 Note: 4572 Currently only correct in parallel for square matrices. 4573 4574 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4575 @*/ 4576 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4577 { 4578 PetscErrorCode ierr; 4579 4580 PetscFunctionBegin; 4581 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4582 PetscValidType(mat,1); 4583 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4584 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4585 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4586 MatCheckPreallocated(mat,1); 4587 4588 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4589 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4590 PetscFunctionReturn(0); 4591 } 4592 4593 /*@C 4594 MatGetRowMin - Gets the minimum value (of the real part) of each 4595 row of the matrix 4596 4597 Logically Collective on Mat 4598 4599 Input Parameters: 4600 . mat - the matrix 4601 4602 Output Parameter: 4603 + v - the vector for storing the maximums 4604 - idx - the indices of the column found for each row (optional) 4605 4606 Level: intermediate 4607 4608 Notes: 4609 The result of this call are the same as if one converted the matrix to dense format 4610 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4611 4612 This code is only implemented for a couple of matrix formats. 4613 4614 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4615 MatGetRowMax() 4616 @*/ 4617 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4618 { 4619 PetscErrorCode ierr; 4620 4621 PetscFunctionBegin; 4622 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4623 PetscValidType(mat,1); 4624 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4625 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4626 if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4627 MatCheckPreallocated(mat,1); 4628 4629 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4630 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4631 PetscFunctionReturn(0); 4632 } 4633 4634 /*@C 4635 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4636 row of the matrix 4637 4638 Logically Collective on Mat 4639 4640 Input Parameters: 4641 . mat - the matrix 4642 4643 Output Parameter: 4644 + v - the vector for storing the minimums 4645 - idx - the indices of the column found for each row (or NULL if not needed) 4646 4647 Level: intermediate 4648 4649 Notes: 4650 if a row is completely empty or has only 0.0 values then the idx[] value for that 4651 row is 0 (the first column). 4652 4653 This code is only implemented for a couple of matrix formats. 4654 4655 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4656 @*/ 4657 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4658 { 4659 PetscErrorCode ierr; 4660 4661 PetscFunctionBegin; 4662 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4663 PetscValidType(mat,1); 4664 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4665 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4666 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4667 MatCheckPreallocated(mat,1); 4668 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 4669 4670 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4671 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4672 PetscFunctionReturn(0); 4673 } 4674 4675 /*@C 4676 MatGetRowMax - Gets the maximum value (of the real part) of each 4677 row of the matrix 4678 4679 Logically Collective on Mat 4680 4681 Input Parameters: 4682 . mat - the matrix 4683 4684 Output Parameter: 4685 + v - the vector for storing the maximums 4686 - idx - the indices of the column found for each row (optional) 4687 4688 Level: intermediate 4689 4690 Notes: 4691 The result of this call are the same as if one converted the matrix to dense format 4692 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4693 4694 This code is only implemented for a couple of matrix formats. 4695 4696 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4697 @*/ 4698 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4699 { 4700 PetscErrorCode ierr; 4701 4702 PetscFunctionBegin; 4703 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4704 PetscValidType(mat,1); 4705 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4706 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4707 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4708 MatCheckPreallocated(mat,1); 4709 4710 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4711 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4712 PetscFunctionReturn(0); 4713 } 4714 4715 /*@C 4716 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4717 row of the matrix 4718 4719 Logically Collective on Mat 4720 4721 Input Parameters: 4722 . mat - the matrix 4723 4724 Output Parameter: 4725 + v - the vector for storing the maximums 4726 - idx - the indices of the column found for each row (or NULL if not needed) 4727 4728 Level: intermediate 4729 4730 Notes: 4731 if a row is completely empty or has only 0.0 values then the idx[] value for that 4732 row is 0 (the first column). 4733 4734 This code is only implemented for a couple of matrix formats. 4735 4736 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4737 @*/ 4738 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4739 { 4740 PetscErrorCode ierr; 4741 4742 PetscFunctionBegin; 4743 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4744 PetscValidType(mat,1); 4745 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4746 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4747 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4748 MatCheckPreallocated(mat,1); 4749 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 4750 4751 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4752 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4753 PetscFunctionReturn(0); 4754 } 4755 4756 /*@ 4757 MatGetRowSum - Gets the sum of each row of the matrix 4758 4759 Logically or Neighborhood Collective on Mat 4760 4761 Input Parameters: 4762 . mat - the matrix 4763 4764 Output Parameter: 4765 . v - the vector for storing the sum of rows 4766 4767 Level: intermediate 4768 4769 Notes: 4770 This code is slow since it is not currently specialized for different formats 4771 4772 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4773 @*/ 4774 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4775 { 4776 Vec ones; 4777 PetscErrorCode ierr; 4778 4779 PetscFunctionBegin; 4780 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4781 PetscValidType(mat,1); 4782 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4783 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4784 MatCheckPreallocated(mat,1); 4785 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr); 4786 ierr = VecSet(ones,1.);CHKERRQ(ierr); 4787 ierr = MatMult(mat,ones,v);CHKERRQ(ierr); 4788 ierr = VecDestroy(&ones);CHKERRQ(ierr); 4789 PetscFunctionReturn(0); 4790 } 4791 4792 /*@ 4793 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4794 4795 Collective on Mat 4796 4797 Input Parameter: 4798 + mat - the matrix to transpose 4799 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 4800 4801 Output Parameters: 4802 . B - the transpose 4803 4804 Notes: 4805 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 4806 4807 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 4808 4809 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4810 4811 Level: intermediate 4812 4813 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4814 @*/ 4815 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4816 { 4817 PetscErrorCode ierr; 4818 4819 PetscFunctionBegin; 4820 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4821 PetscValidType(mat,1); 4822 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4823 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4824 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4825 if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 4826 if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 4827 MatCheckPreallocated(mat,1); 4828 4829 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4830 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 4831 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4832 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 4833 PetscFunctionReturn(0); 4834 } 4835 4836 /*@ 4837 MatIsTranspose - Test whether a matrix is another one's transpose, 4838 or its own, in which case it tests symmetry. 4839 4840 Collective on Mat 4841 4842 Input Parameter: 4843 + A - the matrix to test 4844 - B - the matrix to test against, this can equal the first parameter 4845 4846 Output Parameters: 4847 . flg - the result 4848 4849 Notes: 4850 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4851 has a running time of the order of the number of nonzeros; the parallel 4852 test involves parallel copies of the block-offdiagonal parts of the matrix. 4853 4854 Level: intermediate 4855 4856 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 4857 @*/ 4858 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4859 { 4860 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4861 4862 PetscFunctionBegin; 4863 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4864 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4865 PetscValidBoolPointer(flg,3); 4866 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 4867 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 4868 *flg = PETSC_FALSE; 4869 if (f && g) { 4870 if (f == g) { 4871 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4872 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 4873 } else { 4874 MatType mattype; 4875 if (!f) { 4876 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 4877 } else { 4878 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 4879 } 4880 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for transpose",mattype); 4881 } 4882 PetscFunctionReturn(0); 4883 } 4884 4885 /*@ 4886 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 4887 4888 Collective on Mat 4889 4890 Input Parameter: 4891 + mat - the matrix to transpose and complex conjugate 4892 - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose 4893 4894 Output Parameters: 4895 . B - the Hermitian 4896 4897 Level: intermediate 4898 4899 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4900 @*/ 4901 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 4902 { 4903 PetscErrorCode ierr; 4904 4905 PetscFunctionBegin; 4906 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 4907 #if defined(PETSC_USE_COMPLEX) 4908 ierr = MatConjugate(*B);CHKERRQ(ierr); 4909 #endif 4910 PetscFunctionReturn(0); 4911 } 4912 4913 /*@ 4914 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 4915 4916 Collective on Mat 4917 4918 Input Parameter: 4919 + A - the matrix to test 4920 - B - the matrix to test against, this can equal the first parameter 4921 4922 Output Parameters: 4923 . flg - the result 4924 4925 Notes: 4926 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4927 has a running time of the order of the number of nonzeros; the parallel 4928 test involves parallel copies of the block-offdiagonal parts of the matrix. 4929 4930 Level: intermediate 4931 4932 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 4933 @*/ 4934 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4935 { 4936 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4937 4938 PetscFunctionBegin; 4939 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4940 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4941 PetscValidBoolPointer(flg,3); 4942 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 4943 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 4944 if (f && g) { 4945 if (f==g) { 4946 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4947 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 4948 } 4949 PetscFunctionReturn(0); 4950 } 4951 4952 /*@ 4953 MatPermute - Creates a new matrix with rows and columns permuted from the 4954 original. 4955 4956 Collective on Mat 4957 4958 Input Parameters: 4959 + mat - the matrix to permute 4960 . row - row permutation, each processor supplies only the permutation for its rows 4961 - col - column permutation, each processor supplies only the permutation for its columns 4962 4963 Output Parameters: 4964 . B - the permuted matrix 4965 4966 Level: advanced 4967 4968 Note: 4969 The index sets map from row/col of permuted matrix to row/col of original matrix. 4970 The index sets should be on the same communicator as Mat and have the same local sizes. 4971 4972 .seealso: MatGetOrdering(), ISAllGather() 4973 4974 @*/ 4975 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 4976 { 4977 PetscErrorCode ierr; 4978 4979 PetscFunctionBegin; 4980 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4981 PetscValidType(mat,1); 4982 PetscValidHeaderSpecific(row,IS_CLASSID,2); 4983 PetscValidHeaderSpecific(col,IS_CLASSID,3); 4984 PetscValidPointer(B,4); 4985 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4986 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4987 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 4988 MatCheckPreallocated(mat,1); 4989 4990 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 4991 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 4992 PetscFunctionReturn(0); 4993 } 4994 4995 /*@ 4996 MatEqual - Compares two matrices. 4997 4998 Collective on Mat 4999 5000 Input Parameters: 5001 + A - the first matrix 5002 - B - the second matrix 5003 5004 Output Parameter: 5005 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5006 5007 Level: intermediate 5008 5009 @*/ 5010 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5011 { 5012 PetscErrorCode ierr; 5013 5014 PetscFunctionBegin; 5015 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5016 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5017 PetscValidType(A,1); 5018 PetscValidType(B,2); 5019 PetscValidBoolPointer(flg,3); 5020 PetscCheckSameComm(A,1,B,2); 5021 MatCheckPreallocated(B,2); 5022 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5023 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5024 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); 5025 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5026 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 5027 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); 5028 MatCheckPreallocated(A,1); 5029 5030 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 5031 PetscFunctionReturn(0); 5032 } 5033 5034 /*@ 5035 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5036 matrices that are stored as vectors. Either of the two scaling 5037 matrices can be NULL. 5038 5039 Collective on Mat 5040 5041 Input Parameters: 5042 + mat - the matrix to be scaled 5043 . l - the left scaling vector (or NULL) 5044 - r - the right scaling vector (or NULL) 5045 5046 Notes: 5047 MatDiagonalScale() computes A = LAR, where 5048 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5049 The L scales the rows of the matrix, the R scales the columns of the matrix. 5050 5051 Level: intermediate 5052 5053 5054 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5055 @*/ 5056 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5057 { 5058 PetscErrorCode ierr; 5059 5060 PetscFunctionBegin; 5061 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5062 PetscValidType(mat,1); 5063 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5064 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5065 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5066 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5067 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5068 MatCheckPreallocated(mat,1); 5069 5070 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5071 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 5072 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5073 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5074 PetscFunctionReturn(0); 5075 } 5076 5077 /*@ 5078 MatScale - Scales all elements of a matrix by a given number. 5079 5080 Logically Collective on Mat 5081 5082 Input Parameters: 5083 + mat - the matrix to be scaled 5084 - a - the scaling value 5085 5086 Output Parameter: 5087 . mat - the scaled matrix 5088 5089 Level: intermediate 5090 5091 .seealso: MatDiagonalScale() 5092 @*/ 5093 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5094 { 5095 PetscErrorCode ierr; 5096 5097 PetscFunctionBegin; 5098 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5099 PetscValidType(mat,1); 5100 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5101 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5102 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5103 PetscValidLogicalCollectiveScalar(mat,a,2); 5104 MatCheckPreallocated(mat,1); 5105 5106 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5107 if (a != (PetscScalar)1.0) { 5108 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5109 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5110 } 5111 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5112 PetscFunctionReturn(0); 5113 } 5114 5115 /*@ 5116 MatNorm - Calculates various norms of a matrix. 5117 5118 Collective on Mat 5119 5120 Input Parameters: 5121 + mat - the matrix 5122 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5123 5124 Output Parameters: 5125 . nrm - the resulting norm 5126 5127 Level: intermediate 5128 5129 @*/ 5130 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5131 { 5132 PetscErrorCode ierr; 5133 5134 PetscFunctionBegin; 5135 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5136 PetscValidType(mat,1); 5137 PetscValidScalarPointer(nrm,3); 5138 5139 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5140 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5141 if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5142 MatCheckPreallocated(mat,1); 5143 5144 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5145 PetscFunctionReturn(0); 5146 } 5147 5148 /* 5149 This variable is used to prevent counting of MatAssemblyBegin() that 5150 are called from within a MatAssemblyEnd(). 5151 */ 5152 static PetscInt MatAssemblyEnd_InUse = 0; 5153 /*@ 5154 MatAssemblyBegin - Begins assembling the matrix. This routine should 5155 be called after completing all calls to MatSetValues(). 5156 5157 Collective on Mat 5158 5159 Input Parameters: 5160 + mat - the matrix 5161 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5162 5163 Notes: 5164 MatSetValues() generally caches the values. The matrix is ready to 5165 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5166 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5167 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5168 using the matrix. 5169 5170 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5171 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 5172 a global collective operation requring all processes that share the matrix. 5173 5174 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5175 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5176 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5177 5178 Level: beginner 5179 5180 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5181 @*/ 5182 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5183 { 5184 PetscErrorCode ierr; 5185 5186 PetscFunctionBegin; 5187 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5188 PetscValidType(mat,1); 5189 MatCheckPreallocated(mat,1); 5190 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5191 if (mat->assembled) { 5192 mat->was_assembled = PETSC_TRUE; 5193 mat->assembled = PETSC_FALSE; 5194 } 5195 5196 if (!MatAssemblyEnd_InUse) { 5197 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5198 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5199 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5200 } else if (mat->ops->assemblybegin) { 5201 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5202 } 5203 PetscFunctionReturn(0); 5204 } 5205 5206 /*@ 5207 MatAssembled - Indicates if a matrix has been assembled and is ready for 5208 use; for example, in matrix-vector product. 5209 5210 Not Collective 5211 5212 Input Parameter: 5213 . mat - the matrix 5214 5215 Output Parameter: 5216 . assembled - PETSC_TRUE or PETSC_FALSE 5217 5218 Level: advanced 5219 5220 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5221 @*/ 5222 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5223 { 5224 PetscFunctionBegin; 5225 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5226 PetscValidPointer(assembled,2); 5227 *assembled = mat->assembled; 5228 PetscFunctionReturn(0); 5229 } 5230 5231 /*@ 5232 MatAssemblyEnd - Completes assembling the matrix. This routine should 5233 be called after MatAssemblyBegin(). 5234 5235 Collective on Mat 5236 5237 Input Parameters: 5238 + mat - the matrix 5239 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5240 5241 Options Database Keys: 5242 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5243 . -mat_view ::ascii_info_detail - Prints more detailed info 5244 . -mat_view - Prints matrix in ASCII format 5245 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5246 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5247 . -display <name> - Sets display name (default is host) 5248 . -draw_pause <sec> - Sets number of seconds to pause after display 5249 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab ) 5250 . -viewer_socket_machine <machine> - Machine to use for socket 5251 . -viewer_socket_port <port> - Port number to use for socket 5252 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5253 5254 Notes: 5255 MatSetValues() generally caches the values. The matrix is ready to 5256 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5257 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5258 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5259 using the matrix. 5260 5261 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5262 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5263 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5264 5265 Level: beginner 5266 5267 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5268 @*/ 5269 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5270 { 5271 PetscErrorCode ierr; 5272 static PetscInt inassm = 0; 5273 PetscBool flg = PETSC_FALSE; 5274 5275 PetscFunctionBegin; 5276 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5277 PetscValidType(mat,1); 5278 5279 inassm++; 5280 MatAssemblyEnd_InUse++; 5281 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5282 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5283 if (mat->ops->assemblyend) { 5284 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5285 } 5286 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5287 } else if (mat->ops->assemblyend) { 5288 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5289 } 5290 5291 /* Flush assembly is not a true assembly */ 5292 if (type != MAT_FLUSH_ASSEMBLY) { 5293 mat->num_ass++; 5294 mat->assembled = PETSC_TRUE; 5295 mat->ass_nonzerostate = mat->nonzerostate; 5296 } 5297 5298 mat->insertmode = NOT_SET_VALUES; 5299 MatAssemblyEnd_InUse--; 5300 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5301 if (!mat->symmetric_eternal) { 5302 mat->symmetric_set = PETSC_FALSE; 5303 mat->hermitian_set = PETSC_FALSE; 5304 mat->structurally_symmetric_set = PETSC_FALSE; 5305 } 5306 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5307 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5308 5309 if (mat->checksymmetryonassembly) { 5310 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5311 if (flg) { 5312 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5313 } else { 5314 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5315 } 5316 } 5317 if (mat->nullsp && mat->checknullspaceonassembly) { 5318 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5319 } 5320 } 5321 inassm--; 5322 PetscFunctionReturn(0); 5323 } 5324 5325 /*@ 5326 MatSetOption - Sets a parameter option for a matrix. Some options 5327 may be specific to certain storage formats. Some options 5328 determine how values will be inserted (or added). Sorted, 5329 row-oriented input will generally assemble the fastest. The default 5330 is row-oriented. 5331 5332 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5333 5334 Input Parameters: 5335 + mat - the matrix 5336 . option - the option, one of those listed below (and possibly others), 5337 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5338 5339 Options Describing Matrix Structure: 5340 + MAT_SPD - symmetric positive definite 5341 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5342 . MAT_HERMITIAN - transpose is the complex conjugation 5343 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5344 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5345 you set to be kept with all future use of the matrix 5346 including after MatAssemblyBegin/End() which could 5347 potentially change the symmetry structure, i.e. you 5348 KNOW the matrix will ALWAYS have the property you set. 5349 5350 5351 Options For Use with MatSetValues(): 5352 Insert a logically dense subblock, which can be 5353 . MAT_ROW_ORIENTED - row-oriented (default) 5354 5355 Note these options reflect the data you pass in with MatSetValues(); it has 5356 nothing to do with how the data is stored internally in the matrix 5357 data structure. 5358 5359 When (re)assembling a matrix, we can restrict the input for 5360 efficiency/debugging purposes. These options include: 5361 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5362 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 5363 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5364 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5365 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5366 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5367 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5368 performance for very large process counts. 5369 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5370 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5371 functions, instead sending only neighbor messages. 5372 5373 Notes: 5374 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5375 5376 Some options are relevant only for particular matrix types and 5377 are thus ignored by others. Other options are not supported by 5378 certain matrix types and will generate an error message if set. 5379 5380 If using a Fortran 77 module to compute a matrix, one may need to 5381 use the column-oriented option (or convert to the row-oriented 5382 format). 5383 5384 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5385 that would generate a new entry in the nonzero structure is instead 5386 ignored. Thus, if memory has not alredy been allocated for this particular 5387 data, then the insertion is ignored. For dense matrices, in which 5388 the entire array is allocated, no entries are ever ignored. 5389 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5390 5391 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5392 that would generate a new entry in the nonzero structure instead produces 5393 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 5394 5395 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5396 that would generate a new entry that has not been preallocated will 5397 instead produce an error. (Currently supported for AIJ and BAIJ formats 5398 only.) This is a useful flag when debugging matrix memory preallocation. 5399 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5400 5401 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5402 other processors should be dropped, rather than stashed. 5403 This is useful if you know that the "owning" processor is also 5404 always generating the correct matrix entries, so that PETSc need 5405 not transfer duplicate entries generated on another processor. 5406 5407 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5408 searches during matrix assembly. When this flag is set, the hash table 5409 is created during the first Matrix Assembly. This hash table is 5410 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5411 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5412 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5413 supported by MATMPIBAIJ format only. 5414 5415 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5416 are kept in the nonzero structure 5417 5418 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5419 a zero location in the matrix 5420 5421 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5422 5423 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5424 zero row routines and thus improves performance for very large process counts. 5425 5426 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5427 part of the matrix (since they should match the upper triangular part). 5428 5429 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5430 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5431 with finite difference schemes with non-periodic boundary conditions. 5432 Notes: 5433 Can only be called after MatSetSizes() and MatSetType() have been set. 5434 5435 Level: intermediate 5436 5437 .seealso: MatOption, Mat 5438 5439 @*/ 5440 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5441 { 5442 PetscErrorCode ierr; 5443 5444 PetscFunctionBegin; 5445 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5446 PetscValidType(mat,1); 5447 if (op > 0) { 5448 PetscValidLogicalCollectiveEnum(mat,op,2); 5449 PetscValidLogicalCollectiveBool(mat,flg,3); 5450 } 5451 5452 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); 5453 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()"); 5454 5455 switch (op) { 5456 case MAT_NO_OFF_PROC_ENTRIES: 5457 mat->nooffprocentries = flg; 5458 PetscFunctionReturn(0); 5459 break; 5460 case MAT_SUBSET_OFF_PROC_ENTRIES: 5461 mat->assembly_subset = flg; 5462 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5463 #if !defined(PETSC_HAVE_MPIUNI) 5464 ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr); 5465 #endif 5466 mat->stash.first_assembly_done = PETSC_FALSE; 5467 } 5468 PetscFunctionReturn(0); 5469 case MAT_NO_OFF_PROC_ZERO_ROWS: 5470 mat->nooffproczerorows = flg; 5471 PetscFunctionReturn(0); 5472 break; 5473 case MAT_SPD: 5474 mat->spd_set = PETSC_TRUE; 5475 mat->spd = flg; 5476 if (flg) { 5477 mat->symmetric = PETSC_TRUE; 5478 mat->structurally_symmetric = PETSC_TRUE; 5479 mat->symmetric_set = PETSC_TRUE; 5480 mat->structurally_symmetric_set = PETSC_TRUE; 5481 } 5482 break; 5483 case MAT_SYMMETRIC: 5484 mat->symmetric = flg; 5485 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5486 mat->symmetric_set = PETSC_TRUE; 5487 mat->structurally_symmetric_set = flg; 5488 #if !defined(PETSC_USE_COMPLEX) 5489 mat->hermitian = flg; 5490 mat->hermitian_set = PETSC_TRUE; 5491 #endif 5492 break; 5493 case MAT_HERMITIAN: 5494 mat->hermitian = flg; 5495 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5496 mat->hermitian_set = PETSC_TRUE; 5497 mat->structurally_symmetric_set = flg; 5498 #if !defined(PETSC_USE_COMPLEX) 5499 mat->symmetric = flg; 5500 mat->symmetric_set = PETSC_TRUE; 5501 #endif 5502 break; 5503 case MAT_STRUCTURALLY_SYMMETRIC: 5504 mat->structurally_symmetric = flg; 5505 mat->structurally_symmetric_set = PETSC_TRUE; 5506 break; 5507 case MAT_SYMMETRY_ETERNAL: 5508 mat->symmetric_eternal = flg; 5509 break; 5510 case MAT_STRUCTURE_ONLY: 5511 mat->structure_only = flg; 5512 break; 5513 case MAT_SORTED_FULL: 5514 mat->sortedfull = flg; 5515 break; 5516 default: 5517 break; 5518 } 5519 if (mat->ops->setoption) { 5520 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5521 } 5522 PetscFunctionReturn(0); 5523 } 5524 5525 /*@ 5526 MatGetOption - Gets a parameter option that has been set for a matrix. 5527 5528 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5529 5530 Input Parameters: 5531 + mat - the matrix 5532 - option - the option, this only responds to certain options, check the code for which ones 5533 5534 Output Parameter: 5535 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5536 5537 Notes: 5538 Can only be called after MatSetSizes() and MatSetType() have been set. 5539 5540 Level: intermediate 5541 5542 .seealso: MatOption, MatSetOption() 5543 5544 @*/ 5545 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5546 { 5547 PetscFunctionBegin; 5548 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5549 PetscValidType(mat,1); 5550 5551 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); 5552 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()"); 5553 5554 switch (op) { 5555 case MAT_NO_OFF_PROC_ENTRIES: 5556 *flg = mat->nooffprocentries; 5557 break; 5558 case MAT_NO_OFF_PROC_ZERO_ROWS: 5559 *flg = mat->nooffproczerorows; 5560 break; 5561 case MAT_SYMMETRIC: 5562 *flg = mat->symmetric; 5563 break; 5564 case MAT_HERMITIAN: 5565 *flg = mat->hermitian; 5566 break; 5567 case MAT_STRUCTURALLY_SYMMETRIC: 5568 *flg = mat->structurally_symmetric; 5569 break; 5570 case MAT_SYMMETRY_ETERNAL: 5571 *flg = mat->symmetric_eternal; 5572 break; 5573 case MAT_SPD: 5574 *flg = mat->spd; 5575 break; 5576 default: 5577 break; 5578 } 5579 PetscFunctionReturn(0); 5580 } 5581 5582 /*@ 5583 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5584 this routine retains the old nonzero structure. 5585 5586 Logically Collective on Mat 5587 5588 Input Parameters: 5589 . mat - the matrix 5590 5591 Level: intermediate 5592 5593 Notes: 5594 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. 5595 See the Performance chapter of the users manual for information on preallocating matrices. 5596 5597 .seealso: MatZeroRows() 5598 @*/ 5599 PetscErrorCode MatZeroEntries(Mat mat) 5600 { 5601 PetscErrorCode ierr; 5602 5603 PetscFunctionBegin; 5604 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5605 PetscValidType(mat,1); 5606 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5607 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"); 5608 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5609 MatCheckPreallocated(mat,1); 5610 5611 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5612 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5613 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5614 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5615 PetscFunctionReturn(0); 5616 } 5617 5618 /*@ 5619 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5620 of a set of rows and columns of a matrix. 5621 5622 Collective on Mat 5623 5624 Input Parameters: 5625 + mat - the matrix 5626 . numRows - the number of rows to remove 5627 . rows - the global row indices 5628 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5629 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5630 - b - optional vector of right hand side, that will be adjusted by provided solution 5631 5632 Notes: 5633 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5634 5635 The user can set a value in the diagonal entry (or for the AIJ and 5636 row formats can optionally remove the main diagonal entry from the 5637 nonzero structure as well, by passing 0.0 as the final argument). 5638 5639 For the parallel case, all processes that share the matrix (i.e., 5640 those in the communicator used for matrix creation) MUST call this 5641 routine, regardless of whether any rows being zeroed are owned by 5642 them. 5643 5644 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5645 list only rows local to itself). 5646 5647 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5648 5649 Level: intermediate 5650 5651 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5652 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5653 @*/ 5654 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5655 { 5656 PetscErrorCode ierr; 5657 5658 PetscFunctionBegin; 5659 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5660 PetscValidType(mat,1); 5661 if (numRows) PetscValidIntPointer(rows,3); 5662 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5663 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5664 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5665 MatCheckPreallocated(mat,1); 5666 5667 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5668 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5669 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5670 PetscFunctionReturn(0); 5671 } 5672 5673 /*@ 5674 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5675 of a set of rows and columns of a matrix. 5676 5677 Collective on Mat 5678 5679 Input Parameters: 5680 + mat - the matrix 5681 . is - the rows to zero 5682 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5683 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5684 - b - optional vector of right hand side, that will be adjusted by provided solution 5685 5686 Notes: 5687 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5688 5689 The user can set a value in the diagonal entry (or for the AIJ and 5690 row formats can optionally remove the main diagonal entry from the 5691 nonzero structure as well, by passing 0.0 as the final argument). 5692 5693 For the parallel case, all processes that share the matrix (i.e., 5694 those in the communicator used for matrix creation) MUST call this 5695 routine, regardless of whether any rows being zeroed are owned by 5696 them. 5697 5698 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5699 list only rows local to itself). 5700 5701 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5702 5703 Level: intermediate 5704 5705 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5706 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 5707 @*/ 5708 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5709 { 5710 PetscErrorCode ierr; 5711 PetscInt numRows; 5712 const PetscInt *rows; 5713 5714 PetscFunctionBegin; 5715 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5716 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5717 PetscValidType(mat,1); 5718 PetscValidType(is,2); 5719 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5720 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5721 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5722 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5723 PetscFunctionReturn(0); 5724 } 5725 5726 /*@ 5727 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5728 of a set of rows of a matrix. 5729 5730 Collective on Mat 5731 5732 Input Parameters: 5733 + mat - the matrix 5734 . numRows - the number of rows to remove 5735 . rows - the global row indices 5736 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5737 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5738 - b - optional vector of right hand side, that will be adjusted by provided solution 5739 5740 Notes: 5741 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5742 but does not release memory. For the dense and block diagonal 5743 formats this does not alter the nonzero structure. 5744 5745 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5746 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5747 merely zeroed. 5748 5749 The user can set a value in the diagonal entry (or for the AIJ and 5750 row formats can optionally remove the main diagonal entry from the 5751 nonzero structure as well, by passing 0.0 as the final argument). 5752 5753 For the parallel case, all processes that share the matrix (i.e., 5754 those in the communicator used for matrix creation) MUST call this 5755 routine, regardless of whether any rows being zeroed are owned by 5756 them. 5757 5758 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5759 list only rows local to itself). 5760 5761 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5762 owns that are to be zeroed. This saves a global synchronization in the implementation. 5763 5764 Level: intermediate 5765 5766 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5767 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5768 @*/ 5769 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5770 { 5771 PetscErrorCode ierr; 5772 5773 PetscFunctionBegin; 5774 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5775 PetscValidType(mat,1); 5776 if (numRows) PetscValidIntPointer(rows,3); 5777 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5778 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5779 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5780 MatCheckPreallocated(mat,1); 5781 5782 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5783 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5784 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5785 PetscFunctionReturn(0); 5786 } 5787 5788 /*@ 5789 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5790 of a set of rows of a matrix. 5791 5792 Collective on Mat 5793 5794 Input Parameters: 5795 + mat - the matrix 5796 . is - index set of rows to remove 5797 . diag - value put in all diagonals of eliminated rows 5798 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5799 - b - optional vector of right hand side, that will be adjusted by provided solution 5800 5801 Notes: 5802 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5803 but does not release memory. For the dense and block diagonal 5804 formats this does not alter the nonzero structure. 5805 5806 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5807 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5808 merely zeroed. 5809 5810 The user can set a value in the diagonal entry (or for the AIJ and 5811 row formats can optionally remove the main diagonal entry from the 5812 nonzero structure as well, by passing 0.0 as the final argument). 5813 5814 For the parallel case, all processes that share the matrix (i.e., 5815 those in the communicator used for matrix creation) MUST call this 5816 routine, regardless of whether any rows being zeroed are owned by 5817 them. 5818 5819 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5820 list only rows local to itself). 5821 5822 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5823 owns that are to be zeroed. This saves a global synchronization in the implementation. 5824 5825 Level: intermediate 5826 5827 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5828 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5829 @*/ 5830 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5831 { 5832 PetscInt numRows; 5833 const PetscInt *rows; 5834 PetscErrorCode ierr; 5835 5836 PetscFunctionBegin; 5837 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5838 PetscValidType(mat,1); 5839 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5840 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5841 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5842 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5843 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5844 PetscFunctionReturn(0); 5845 } 5846 5847 /*@ 5848 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 5849 of a set of rows of a matrix. These rows must be local to the process. 5850 5851 Collective on Mat 5852 5853 Input Parameters: 5854 + mat - the matrix 5855 . numRows - the number of rows to remove 5856 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5857 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5858 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5859 - b - optional vector of right hand side, that will be adjusted by provided solution 5860 5861 Notes: 5862 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5863 but does not release memory. For the dense and block diagonal 5864 formats this does not alter the nonzero structure. 5865 5866 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5867 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5868 merely zeroed. 5869 5870 The user can set a value in the diagonal entry (or for the AIJ and 5871 row formats can optionally remove the main diagonal entry from the 5872 nonzero structure as well, by passing 0.0 as the final argument). 5873 5874 For the parallel case, all processes that share the matrix (i.e., 5875 those in the communicator used for matrix creation) MUST call this 5876 routine, regardless of whether any rows being zeroed are owned by 5877 them. 5878 5879 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5880 list only rows local to itself). 5881 5882 The grid coordinates are across the entire grid, not just the local portion 5883 5884 In Fortran idxm and idxn should be declared as 5885 $ MatStencil idxm(4,m) 5886 and the values inserted using 5887 $ idxm(MatStencil_i,1) = i 5888 $ idxm(MatStencil_j,1) = j 5889 $ idxm(MatStencil_k,1) = k 5890 $ idxm(MatStencil_c,1) = c 5891 etc 5892 5893 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5894 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5895 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5896 DM_BOUNDARY_PERIODIC boundary type. 5897 5898 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 5899 a single value per point) you can skip filling those indices. 5900 5901 Level: intermediate 5902 5903 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5904 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5905 @*/ 5906 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5907 { 5908 PetscInt dim = mat->stencil.dim; 5909 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5910 PetscInt *dims = mat->stencil.dims+1; 5911 PetscInt *starts = mat->stencil.starts; 5912 PetscInt *dxm = (PetscInt*) rows; 5913 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5914 PetscErrorCode ierr; 5915 5916 PetscFunctionBegin; 5917 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5918 PetscValidType(mat,1); 5919 if (numRows) PetscValidIntPointer(rows,3); 5920 5921 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 5922 for (i = 0; i < numRows; ++i) { 5923 /* Skip unused dimensions (they are ordered k, j, i, c) */ 5924 for (j = 0; j < 3-sdim; ++j) dxm++; 5925 /* Local index in X dir */ 5926 tmp = *dxm++ - starts[0]; 5927 /* Loop over remaining dimensions */ 5928 for (j = 0; j < dim-1; ++j) { 5929 /* If nonlocal, set index to be negative */ 5930 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 5931 /* Update local index */ 5932 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 5933 } 5934 /* Skip component slot if necessary */ 5935 if (mat->stencil.noc) dxm++; 5936 /* Local row number */ 5937 if (tmp >= 0) { 5938 jdxm[numNewRows++] = tmp; 5939 } 5940 } 5941 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 5942 ierr = PetscFree(jdxm);CHKERRQ(ierr); 5943 PetscFunctionReturn(0); 5944 } 5945 5946 /*@ 5947 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 5948 of a set of rows and columns of a matrix. 5949 5950 Collective on Mat 5951 5952 Input Parameters: 5953 + mat - the matrix 5954 . numRows - the number of rows/columns to remove 5955 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5956 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5957 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5958 - b - optional vector of right hand side, that will be adjusted by provided solution 5959 5960 Notes: 5961 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5962 but does not release memory. For the dense and block diagonal 5963 formats this does not alter the nonzero structure. 5964 5965 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5966 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5967 merely zeroed. 5968 5969 The user can set a value in the diagonal entry (or for the AIJ and 5970 row formats can optionally remove the main diagonal entry from the 5971 nonzero structure as well, by passing 0.0 as the final argument). 5972 5973 For the parallel case, all processes that share the matrix (i.e., 5974 those in the communicator used for matrix creation) MUST call this 5975 routine, regardless of whether any rows being zeroed are owned by 5976 them. 5977 5978 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5979 list only rows local to itself, but the row/column numbers are given in local numbering). 5980 5981 The grid coordinates are across the entire grid, not just the local portion 5982 5983 In Fortran idxm and idxn should be declared as 5984 $ MatStencil idxm(4,m) 5985 and the values inserted using 5986 $ idxm(MatStencil_i,1) = i 5987 $ idxm(MatStencil_j,1) = j 5988 $ idxm(MatStencil_k,1) = k 5989 $ idxm(MatStencil_c,1) = c 5990 etc 5991 5992 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5993 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5994 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5995 DM_BOUNDARY_PERIODIC boundary type. 5996 5997 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 5998 a single value per point) you can skip filling those indices. 5999 6000 Level: intermediate 6001 6002 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6003 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 6004 @*/ 6005 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6006 { 6007 PetscInt dim = mat->stencil.dim; 6008 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6009 PetscInt *dims = mat->stencil.dims+1; 6010 PetscInt *starts = mat->stencil.starts; 6011 PetscInt *dxm = (PetscInt*) rows; 6012 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6013 PetscErrorCode ierr; 6014 6015 PetscFunctionBegin; 6016 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6017 PetscValidType(mat,1); 6018 if (numRows) PetscValidIntPointer(rows,3); 6019 6020 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6021 for (i = 0; i < numRows; ++i) { 6022 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6023 for (j = 0; j < 3-sdim; ++j) dxm++; 6024 /* Local index in X dir */ 6025 tmp = *dxm++ - starts[0]; 6026 /* Loop over remaining dimensions */ 6027 for (j = 0; j < dim-1; ++j) { 6028 /* If nonlocal, set index to be negative */ 6029 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6030 /* Update local index */ 6031 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6032 } 6033 /* Skip component slot if necessary */ 6034 if (mat->stencil.noc) dxm++; 6035 /* Local row number */ 6036 if (tmp >= 0) { 6037 jdxm[numNewRows++] = tmp; 6038 } 6039 } 6040 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6041 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6042 PetscFunctionReturn(0); 6043 } 6044 6045 /*@C 6046 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6047 of a set of rows of a matrix; using local numbering of rows. 6048 6049 Collective on Mat 6050 6051 Input Parameters: 6052 + mat - the matrix 6053 . numRows - the number of rows to remove 6054 . rows - the global row indices 6055 . diag - value put in all diagonals of eliminated rows 6056 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6057 - b - optional vector of right hand side, that will be adjusted by provided solution 6058 6059 Notes: 6060 Before calling MatZeroRowsLocal(), the user must first set the 6061 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6062 6063 For the AIJ matrix formats this removes the old nonzero structure, 6064 but does not release memory. For the dense and block diagonal 6065 formats this does not alter the nonzero structure. 6066 6067 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6068 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6069 merely zeroed. 6070 6071 The user can set a value in the diagonal entry (or for the AIJ and 6072 row formats can optionally remove the main diagonal entry from the 6073 nonzero structure as well, by passing 0.0 as the final argument). 6074 6075 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6076 owns that are to be zeroed. This saves a global synchronization in the implementation. 6077 6078 Level: intermediate 6079 6080 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6081 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6082 @*/ 6083 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6084 { 6085 PetscErrorCode ierr; 6086 6087 PetscFunctionBegin; 6088 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6089 PetscValidType(mat,1); 6090 if (numRows) PetscValidIntPointer(rows,3); 6091 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6092 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6093 MatCheckPreallocated(mat,1); 6094 6095 if (mat->ops->zerorowslocal) { 6096 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6097 } else { 6098 IS is, newis; 6099 const PetscInt *newRows; 6100 6101 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6102 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6103 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 6104 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6105 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6106 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6107 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6108 ierr = ISDestroy(&is);CHKERRQ(ierr); 6109 } 6110 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6111 PetscFunctionReturn(0); 6112 } 6113 6114 /*@ 6115 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6116 of a set of rows of a matrix; using local numbering of rows. 6117 6118 Collective on Mat 6119 6120 Input Parameters: 6121 + mat - the matrix 6122 . is - index set of rows to remove 6123 . diag - value put in all diagonals of eliminated rows 6124 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6125 - b - optional vector of right hand side, that will be adjusted by provided solution 6126 6127 Notes: 6128 Before calling MatZeroRowsLocalIS(), the user must first set the 6129 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6130 6131 For the AIJ matrix formats this removes the old nonzero structure, 6132 but does not release memory. For the dense and block diagonal 6133 formats this does not alter the nonzero structure. 6134 6135 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6136 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6137 merely zeroed. 6138 6139 The user can set a value in the diagonal entry (or for the AIJ and 6140 row formats can optionally remove the main diagonal entry from the 6141 nonzero structure as well, by passing 0.0 as the final argument). 6142 6143 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6144 owns that are to be zeroed. This saves a global synchronization in the implementation. 6145 6146 Level: intermediate 6147 6148 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6149 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6150 @*/ 6151 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6152 { 6153 PetscErrorCode ierr; 6154 PetscInt numRows; 6155 const PetscInt *rows; 6156 6157 PetscFunctionBegin; 6158 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6159 PetscValidType(mat,1); 6160 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6161 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6162 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6163 MatCheckPreallocated(mat,1); 6164 6165 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6166 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6167 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6168 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6169 PetscFunctionReturn(0); 6170 } 6171 6172 /*@ 6173 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6174 of a set of rows and columns of a matrix; using local numbering of rows. 6175 6176 Collective on Mat 6177 6178 Input Parameters: 6179 + mat - the matrix 6180 . numRows - the number of rows to remove 6181 . rows - the global row indices 6182 . diag - value put in all diagonals of eliminated rows 6183 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6184 - b - optional vector of right hand side, that will be adjusted by provided solution 6185 6186 Notes: 6187 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6188 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6189 6190 The user can set a value in the diagonal entry (or for the AIJ and 6191 row formats can optionally remove the main diagonal entry from the 6192 nonzero structure as well, by passing 0.0 as the final argument). 6193 6194 Level: intermediate 6195 6196 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6197 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6198 @*/ 6199 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6200 { 6201 PetscErrorCode ierr; 6202 IS is, newis; 6203 const PetscInt *newRows; 6204 6205 PetscFunctionBegin; 6206 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6207 PetscValidType(mat,1); 6208 if (numRows) PetscValidIntPointer(rows,3); 6209 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6210 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6211 MatCheckPreallocated(mat,1); 6212 6213 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6214 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6215 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6216 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6217 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6218 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6219 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6220 ierr = ISDestroy(&is);CHKERRQ(ierr); 6221 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6222 PetscFunctionReturn(0); 6223 } 6224 6225 /*@ 6226 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6227 of a set of rows and columns of a matrix; using local numbering of rows. 6228 6229 Collective on Mat 6230 6231 Input Parameters: 6232 + mat - the matrix 6233 . is - index set of rows to remove 6234 . diag - value put in all diagonals of eliminated rows 6235 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6236 - b - optional vector of right hand side, that will be adjusted by provided solution 6237 6238 Notes: 6239 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6240 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6241 6242 The user can set a value in the diagonal entry (or for the AIJ and 6243 row formats can optionally remove the main diagonal entry from the 6244 nonzero structure as well, by passing 0.0 as the final argument). 6245 6246 Level: intermediate 6247 6248 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6249 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6250 @*/ 6251 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6252 { 6253 PetscErrorCode ierr; 6254 PetscInt numRows; 6255 const PetscInt *rows; 6256 6257 PetscFunctionBegin; 6258 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6259 PetscValidType(mat,1); 6260 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6261 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6262 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6263 MatCheckPreallocated(mat,1); 6264 6265 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6266 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6267 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6268 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6269 PetscFunctionReturn(0); 6270 } 6271 6272 /*@C 6273 MatGetSize - Returns the numbers of rows and columns in a matrix. 6274 6275 Not Collective 6276 6277 Input Parameter: 6278 . mat - the matrix 6279 6280 Output Parameters: 6281 + m - the number of global rows 6282 - n - the number of global columns 6283 6284 Note: both output parameters can be NULL on input. 6285 6286 Level: beginner 6287 6288 .seealso: MatGetLocalSize() 6289 @*/ 6290 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6291 { 6292 PetscFunctionBegin; 6293 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6294 if (m) *m = mat->rmap->N; 6295 if (n) *n = mat->cmap->N; 6296 PetscFunctionReturn(0); 6297 } 6298 6299 /*@C 6300 MatGetLocalSize - Returns the number of rows and columns in a matrix 6301 stored locally. This information may be implementation dependent, so 6302 use with care. 6303 6304 Not Collective 6305 6306 Input Parameters: 6307 . mat - the matrix 6308 6309 Output Parameters: 6310 + m - the number of local rows 6311 - n - the number of local columns 6312 6313 Note: both output parameters can be NULL on input. 6314 6315 Level: beginner 6316 6317 .seealso: MatGetSize() 6318 @*/ 6319 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6320 { 6321 PetscFunctionBegin; 6322 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6323 if (m) PetscValidIntPointer(m,2); 6324 if (n) PetscValidIntPointer(n,3); 6325 if (m) *m = mat->rmap->n; 6326 if (n) *n = mat->cmap->n; 6327 PetscFunctionReturn(0); 6328 } 6329 6330 /*@C 6331 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6332 this processor. (The columns of the "diagonal block") 6333 6334 Not Collective, unless matrix has not been allocated, then collective on Mat 6335 6336 Input Parameters: 6337 . mat - the matrix 6338 6339 Output Parameters: 6340 + m - the global index of the first local column 6341 - n - one more than the global index of the last local column 6342 6343 Notes: 6344 both output parameters can be NULL on input. 6345 6346 Level: developer 6347 6348 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6349 6350 @*/ 6351 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6352 { 6353 PetscFunctionBegin; 6354 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6355 PetscValidType(mat,1); 6356 if (m) PetscValidIntPointer(m,2); 6357 if (n) PetscValidIntPointer(n,3); 6358 MatCheckPreallocated(mat,1); 6359 if (m) *m = mat->cmap->rstart; 6360 if (n) *n = mat->cmap->rend; 6361 PetscFunctionReturn(0); 6362 } 6363 6364 /*@C 6365 MatGetOwnershipRange - Returns the range of matrix rows owned by 6366 this processor, assuming that the matrix is laid out with the first 6367 n1 rows on the first processor, the next n2 rows on the second, etc. 6368 For certain parallel layouts this range may not be well defined. 6369 6370 Not Collective 6371 6372 Input Parameters: 6373 . mat - the matrix 6374 6375 Output Parameters: 6376 + m - the global index of the first local row 6377 - n - one more than the global index of the last local row 6378 6379 Note: Both output parameters can be NULL on input. 6380 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6381 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6382 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6383 6384 Level: beginner 6385 6386 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6387 6388 @*/ 6389 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6390 { 6391 PetscFunctionBegin; 6392 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6393 PetscValidType(mat,1); 6394 if (m) PetscValidIntPointer(m,2); 6395 if (n) PetscValidIntPointer(n,3); 6396 MatCheckPreallocated(mat,1); 6397 if (m) *m = mat->rmap->rstart; 6398 if (n) *n = mat->rmap->rend; 6399 PetscFunctionReturn(0); 6400 } 6401 6402 /*@C 6403 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6404 each process 6405 6406 Not Collective, unless matrix has not been allocated, then collective on Mat 6407 6408 Input Parameters: 6409 . mat - the matrix 6410 6411 Output Parameters: 6412 . ranges - start of each processors portion plus one more than the total length at the end 6413 6414 Level: beginner 6415 6416 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6417 6418 @*/ 6419 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6420 { 6421 PetscErrorCode ierr; 6422 6423 PetscFunctionBegin; 6424 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6425 PetscValidType(mat,1); 6426 MatCheckPreallocated(mat,1); 6427 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6428 PetscFunctionReturn(0); 6429 } 6430 6431 /*@C 6432 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6433 this processor. (The columns of the "diagonal blocks" for each process) 6434 6435 Not Collective, unless matrix has not been allocated, then collective on Mat 6436 6437 Input Parameters: 6438 . mat - the matrix 6439 6440 Output Parameters: 6441 . ranges - start of each processors portion plus one more then the total length at the end 6442 6443 Level: beginner 6444 6445 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6446 6447 @*/ 6448 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6449 { 6450 PetscErrorCode ierr; 6451 6452 PetscFunctionBegin; 6453 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6454 PetscValidType(mat,1); 6455 MatCheckPreallocated(mat,1); 6456 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6457 PetscFunctionReturn(0); 6458 } 6459 6460 /*@C 6461 MatGetOwnershipIS - Get row and column ownership as index sets 6462 6463 Not Collective 6464 6465 Input Arguments: 6466 . A - matrix of type Elemental 6467 6468 Output Arguments: 6469 + rows - rows in which this process owns elements 6470 - cols - columns in which this process owns elements 6471 6472 Level: intermediate 6473 6474 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL 6475 @*/ 6476 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6477 { 6478 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6479 6480 PetscFunctionBegin; 6481 MatCheckPreallocated(A,1); 6482 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6483 if (f) { 6484 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6485 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6486 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6487 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6488 } 6489 PetscFunctionReturn(0); 6490 } 6491 6492 /*@C 6493 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6494 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6495 to complete the factorization. 6496 6497 Collective on Mat 6498 6499 Input Parameters: 6500 + mat - the matrix 6501 . row - row permutation 6502 . column - column permutation 6503 - info - structure containing 6504 $ levels - number of levels of fill. 6505 $ expected fill - as ratio of original fill. 6506 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6507 missing diagonal entries) 6508 6509 Output Parameters: 6510 . fact - new matrix that has been symbolically factored 6511 6512 Notes: 6513 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6514 6515 Most users should employ the simplified KSP interface for linear solvers 6516 instead of working directly with matrix algebra routines such as this. 6517 See, e.g., KSPCreate(). 6518 6519 Level: developer 6520 6521 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6522 MatGetOrdering(), MatFactorInfo 6523 6524 Note: this uses the definition of level of fill as in Y. Saad, 2003 6525 6526 Developer Note: fortran interface is not autogenerated as the f90 6527 interface defintion cannot be generated correctly [due to MatFactorInfo] 6528 6529 References: 6530 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6531 @*/ 6532 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6533 { 6534 PetscErrorCode ierr; 6535 6536 PetscFunctionBegin; 6537 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6538 PetscValidType(mat,1); 6539 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6540 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6541 PetscValidPointer(info,4); 6542 PetscValidPointer(fact,5); 6543 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6544 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6545 if (!(fact)->ops->ilufactorsymbolic) { 6546 MatSolverType spackage; 6547 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6548 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6549 } 6550 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6551 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6552 MatCheckPreallocated(mat,2); 6553 6554 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6555 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6556 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6557 PetscFunctionReturn(0); 6558 } 6559 6560 /*@C 6561 MatICCFactorSymbolic - Performs symbolic incomplete 6562 Cholesky factorization for a symmetric matrix. Use 6563 MatCholeskyFactorNumeric() to complete the factorization. 6564 6565 Collective on Mat 6566 6567 Input Parameters: 6568 + mat - the matrix 6569 . perm - row and column permutation 6570 - info - structure containing 6571 $ levels - number of levels of fill. 6572 $ expected fill - as ratio of original fill. 6573 6574 Output Parameter: 6575 . fact - the factored matrix 6576 6577 Notes: 6578 Most users should employ the KSP interface for linear solvers 6579 instead of working directly with matrix algebra routines such as this. 6580 See, e.g., KSPCreate(). 6581 6582 Level: developer 6583 6584 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6585 6586 Note: this uses the definition of level of fill as in Y. Saad, 2003 6587 6588 Developer Note: fortran interface is not autogenerated as the f90 6589 interface defintion cannot be generated correctly [due to MatFactorInfo] 6590 6591 References: 6592 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6593 @*/ 6594 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6595 { 6596 PetscErrorCode ierr; 6597 6598 PetscFunctionBegin; 6599 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6600 PetscValidType(mat,1); 6601 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6602 PetscValidPointer(info,3); 6603 PetscValidPointer(fact,4); 6604 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6605 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6606 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6607 if (!(fact)->ops->iccfactorsymbolic) { 6608 MatSolverType spackage; 6609 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6610 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6611 } 6612 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6613 MatCheckPreallocated(mat,2); 6614 6615 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6616 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6617 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6618 PetscFunctionReturn(0); 6619 } 6620 6621 /*@C 6622 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6623 points to an array of valid matrices, they may be reused to store the new 6624 submatrices. 6625 6626 Collective on Mat 6627 6628 Input Parameters: 6629 + mat - the matrix 6630 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6631 . irow, icol - index sets of rows and columns to extract 6632 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6633 6634 Output Parameter: 6635 . submat - the array of submatrices 6636 6637 Notes: 6638 MatCreateSubMatrices() can extract ONLY sequential submatrices 6639 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6640 to extract a parallel submatrix. 6641 6642 Some matrix types place restrictions on the row and column 6643 indices, such as that they be sorted or that they be equal to each other. 6644 6645 The index sets may not have duplicate entries. 6646 6647 When extracting submatrices from a parallel matrix, each processor can 6648 form a different submatrix by setting the rows and columns of its 6649 individual index sets according to the local submatrix desired. 6650 6651 When finished using the submatrices, the user should destroy 6652 them with MatDestroySubMatrices(). 6653 6654 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6655 original matrix has not changed from that last call to MatCreateSubMatrices(). 6656 6657 This routine creates the matrices in submat; you should NOT create them before 6658 calling it. It also allocates the array of matrix pointers submat. 6659 6660 For BAIJ matrices the index sets must respect the block structure, that is if they 6661 request one row/column in a block, they must request all rows/columns that are in 6662 that block. For example, if the block size is 2 you cannot request just row 0 and 6663 column 0. 6664 6665 Fortran Note: 6666 The Fortran interface is slightly different from that given below; it 6667 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6668 6669 Level: advanced 6670 6671 6672 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6673 @*/ 6674 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6675 { 6676 PetscErrorCode ierr; 6677 PetscInt i; 6678 PetscBool eq; 6679 6680 PetscFunctionBegin; 6681 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6682 PetscValidType(mat,1); 6683 if (n) { 6684 PetscValidPointer(irow,3); 6685 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6686 PetscValidPointer(icol,4); 6687 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6688 } 6689 PetscValidPointer(submat,6); 6690 if (n && scall == MAT_REUSE_MATRIX) { 6691 PetscValidPointer(*submat,6); 6692 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6693 } 6694 if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6695 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6696 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6697 MatCheckPreallocated(mat,1); 6698 6699 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6700 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6701 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6702 for (i=0; i<n; i++) { 6703 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6704 ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr); 6705 if (eq) { 6706 ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr); 6707 } 6708 } 6709 PetscFunctionReturn(0); 6710 } 6711 6712 /*@C 6713 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6714 6715 Collective on Mat 6716 6717 Input Parameters: 6718 + mat - the matrix 6719 . n - the number of submatrixes to be extracted 6720 . irow, icol - index sets of rows and columns to extract 6721 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6722 6723 Output Parameter: 6724 . submat - the array of submatrices 6725 6726 Level: advanced 6727 6728 6729 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6730 @*/ 6731 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6732 { 6733 PetscErrorCode ierr; 6734 PetscInt i; 6735 PetscBool eq; 6736 6737 PetscFunctionBegin; 6738 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6739 PetscValidType(mat,1); 6740 if (n) { 6741 PetscValidPointer(irow,3); 6742 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6743 PetscValidPointer(icol,4); 6744 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6745 } 6746 PetscValidPointer(submat,6); 6747 if (n && scall == MAT_REUSE_MATRIX) { 6748 PetscValidPointer(*submat,6); 6749 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6750 } 6751 if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6752 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6753 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6754 MatCheckPreallocated(mat,1); 6755 6756 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6757 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6758 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6759 for (i=0; i<n; i++) { 6760 ierr = ISEqualUnsorted(irow[i],icol[i],&eq);CHKERRQ(ierr); 6761 if (eq) { 6762 ierr = MatPropagateSymmetryOptions(mat,(*submat)[i]);CHKERRQ(ierr); 6763 } 6764 } 6765 PetscFunctionReturn(0); 6766 } 6767 6768 /*@C 6769 MatDestroyMatrices - Destroys an array of matrices. 6770 6771 Collective on Mat 6772 6773 Input Parameters: 6774 + n - the number of local matrices 6775 - mat - the matrices (note that this is a pointer to the array of matrices) 6776 6777 Level: advanced 6778 6779 Notes: 6780 Frees not only the matrices, but also the array that contains the matrices 6781 In Fortran will not free the array. 6782 6783 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 6784 @*/ 6785 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6786 { 6787 PetscErrorCode ierr; 6788 PetscInt i; 6789 6790 PetscFunctionBegin; 6791 if (!*mat) PetscFunctionReturn(0); 6792 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6793 PetscValidPointer(mat,2); 6794 6795 for (i=0; i<n; i++) { 6796 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 6797 } 6798 6799 /* memory is allocated even if n = 0 */ 6800 ierr = PetscFree(*mat);CHKERRQ(ierr); 6801 PetscFunctionReturn(0); 6802 } 6803 6804 /*@C 6805 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 6806 6807 Collective on Mat 6808 6809 Input Parameters: 6810 + n - the number of local matrices 6811 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6812 sequence of MatCreateSubMatrices()) 6813 6814 Level: advanced 6815 6816 Notes: 6817 Frees not only the matrices, but also the array that contains the matrices 6818 In Fortran will not free the array. 6819 6820 .seealso: MatCreateSubMatrices() 6821 @*/ 6822 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 6823 { 6824 PetscErrorCode ierr; 6825 Mat mat0; 6826 6827 PetscFunctionBegin; 6828 if (!*mat) PetscFunctionReturn(0); 6829 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 6830 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6831 PetscValidPointer(mat,2); 6832 6833 mat0 = (*mat)[0]; 6834 if (mat0 && mat0->ops->destroysubmatrices) { 6835 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr); 6836 } else { 6837 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr); 6838 } 6839 PetscFunctionReturn(0); 6840 } 6841 6842 /*@C 6843 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 6844 6845 Collective on Mat 6846 6847 Input Parameters: 6848 . mat - the matrix 6849 6850 Output Parameter: 6851 . matstruct - the sequential matrix with the nonzero structure of mat 6852 6853 Level: intermediate 6854 6855 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 6856 @*/ 6857 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 6858 { 6859 PetscErrorCode ierr; 6860 6861 PetscFunctionBegin; 6862 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6863 PetscValidPointer(matstruct,2); 6864 6865 PetscValidType(mat,1); 6866 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6867 MatCheckPreallocated(mat,1); 6868 6869 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 6870 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6871 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 6872 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6873 PetscFunctionReturn(0); 6874 } 6875 6876 /*@C 6877 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 6878 6879 Collective on Mat 6880 6881 Input Parameters: 6882 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 6883 sequence of MatGetSequentialNonzeroStructure()) 6884 6885 Level: advanced 6886 6887 Notes: 6888 Frees not only the matrices, but also the array that contains the matrices 6889 6890 .seealso: MatGetSeqNonzeroStructure() 6891 @*/ 6892 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 6893 { 6894 PetscErrorCode ierr; 6895 6896 PetscFunctionBegin; 6897 PetscValidPointer(mat,1); 6898 ierr = MatDestroy(mat);CHKERRQ(ierr); 6899 PetscFunctionReturn(0); 6900 } 6901 6902 /*@ 6903 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 6904 replaces the index sets by larger ones that represent submatrices with 6905 additional overlap. 6906 6907 Collective on Mat 6908 6909 Input Parameters: 6910 + mat - the matrix 6911 . n - the number of index sets 6912 . is - the array of index sets (these index sets will changed during the call) 6913 - ov - the additional overlap requested 6914 6915 Options Database: 6916 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 6917 6918 Level: developer 6919 6920 6921 .seealso: MatCreateSubMatrices() 6922 @*/ 6923 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 6924 { 6925 PetscErrorCode ierr; 6926 6927 PetscFunctionBegin; 6928 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6929 PetscValidType(mat,1); 6930 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 6931 if (n) { 6932 PetscValidPointer(is,3); 6933 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 6934 } 6935 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6936 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6937 MatCheckPreallocated(mat,1); 6938 6939 if (!ov) PetscFunctionReturn(0); 6940 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6941 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6942 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 6943 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6944 PetscFunctionReturn(0); 6945 } 6946 6947 6948 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 6949 6950 /*@ 6951 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 6952 a sub communicator, replaces the index sets by larger ones that represent submatrices with 6953 additional overlap. 6954 6955 Collective on Mat 6956 6957 Input Parameters: 6958 + mat - the matrix 6959 . n - the number of index sets 6960 . is - the array of index sets (these index sets will changed during the call) 6961 - ov - the additional overlap requested 6962 6963 Options Database: 6964 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 6965 6966 Level: developer 6967 6968 6969 .seealso: MatCreateSubMatrices() 6970 @*/ 6971 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 6972 { 6973 PetscInt i; 6974 PetscErrorCode ierr; 6975 6976 PetscFunctionBegin; 6977 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6978 PetscValidType(mat,1); 6979 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 6980 if (n) { 6981 PetscValidPointer(is,3); 6982 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 6983 } 6984 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6985 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6986 MatCheckPreallocated(mat,1); 6987 if (!ov) PetscFunctionReturn(0); 6988 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6989 for(i=0; i<n; i++){ 6990 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 6991 } 6992 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6993 PetscFunctionReturn(0); 6994 } 6995 6996 6997 6998 6999 /*@ 7000 MatGetBlockSize - Returns the matrix block size. 7001 7002 Not Collective 7003 7004 Input Parameter: 7005 . mat - the matrix 7006 7007 Output Parameter: 7008 . bs - block size 7009 7010 Notes: 7011 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7012 7013 If the block size has not been set yet this routine returns 1. 7014 7015 Level: intermediate 7016 7017 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7018 @*/ 7019 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7020 { 7021 PetscFunctionBegin; 7022 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7023 PetscValidIntPointer(bs,2); 7024 *bs = PetscAbs(mat->rmap->bs); 7025 PetscFunctionReturn(0); 7026 } 7027 7028 /*@ 7029 MatGetBlockSizes - Returns the matrix block row and column sizes. 7030 7031 Not Collective 7032 7033 Input Parameter: 7034 . mat - the matrix 7035 7036 Output Parameter: 7037 + rbs - row block size 7038 - cbs - column block size 7039 7040 Notes: 7041 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7042 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7043 7044 If a block size has not been set yet this routine returns 1. 7045 7046 Level: intermediate 7047 7048 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7049 @*/ 7050 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7051 { 7052 PetscFunctionBegin; 7053 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7054 if (rbs) PetscValidIntPointer(rbs,2); 7055 if (cbs) PetscValidIntPointer(cbs,3); 7056 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7057 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7058 PetscFunctionReturn(0); 7059 } 7060 7061 /*@ 7062 MatSetBlockSize - Sets the matrix block size. 7063 7064 Logically Collective on Mat 7065 7066 Input Parameters: 7067 + mat - the matrix 7068 - bs - block size 7069 7070 Notes: 7071 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7072 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7073 7074 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7075 is compatible with the matrix local sizes. 7076 7077 Level: intermediate 7078 7079 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7080 @*/ 7081 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7082 { 7083 PetscErrorCode ierr; 7084 7085 PetscFunctionBegin; 7086 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7087 PetscValidLogicalCollectiveInt(mat,bs,2); 7088 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr); 7089 PetscFunctionReturn(0); 7090 } 7091 7092 /*@ 7093 MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size 7094 7095 Logically Collective on Mat 7096 7097 Input Parameters: 7098 + mat - the matrix 7099 . nblocks - the number of blocks on this process 7100 - bsizes - the block sizes 7101 7102 Notes: 7103 Currently used by PCVPBJACOBI for SeqAIJ matrices 7104 7105 Level: intermediate 7106 7107 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes() 7108 @*/ 7109 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7110 { 7111 PetscErrorCode ierr; 7112 PetscInt i,ncnt = 0, nlocal; 7113 7114 PetscFunctionBegin; 7115 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7116 if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7117 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr); 7118 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7119 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); 7120 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr); 7121 mat->nblocks = nblocks; 7122 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr); 7123 ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr); 7124 PetscFunctionReturn(0); 7125 } 7126 7127 /*@C 7128 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7129 7130 Logically Collective on Mat 7131 7132 Input Parameters: 7133 . mat - the matrix 7134 7135 Output Parameters: 7136 + nblocks - the number of blocks on this process 7137 - bsizes - the block sizes 7138 7139 Notes: Currently not supported from Fortran 7140 7141 Level: intermediate 7142 7143 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7144 @*/ 7145 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7146 { 7147 PetscFunctionBegin; 7148 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7149 *nblocks = mat->nblocks; 7150 *bsizes = mat->bsizes; 7151 PetscFunctionReturn(0); 7152 } 7153 7154 /*@ 7155 MatSetBlockSizes - Sets the matrix block row and column sizes. 7156 7157 Logically Collective on Mat 7158 7159 Input Parameters: 7160 + mat - the matrix 7161 . rbs - row block size 7162 - cbs - column block size 7163 7164 Notes: 7165 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7166 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7167 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7168 7169 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7170 are compatible with the matrix local sizes. 7171 7172 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7173 7174 Level: intermediate 7175 7176 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7177 @*/ 7178 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7179 { 7180 PetscErrorCode ierr; 7181 7182 PetscFunctionBegin; 7183 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7184 PetscValidLogicalCollectiveInt(mat,rbs,2); 7185 PetscValidLogicalCollectiveInt(mat,cbs,3); 7186 if (mat->ops->setblocksizes) { 7187 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr); 7188 } 7189 if (mat->rmap->refcnt) { 7190 ISLocalToGlobalMapping l2g = NULL; 7191 PetscLayout nmap = NULL; 7192 7193 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr); 7194 if (mat->rmap->mapping) { 7195 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr); 7196 } 7197 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr); 7198 mat->rmap = nmap; 7199 mat->rmap->mapping = l2g; 7200 } 7201 if (mat->cmap->refcnt) { 7202 ISLocalToGlobalMapping l2g = NULL; 7203 PetscLayout nmap = NULL; 7204 7205 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr); 7206 if (mat->cmap->mapping) { 7207 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr); 7208 } 7209 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 7210 mat->cmap = nmap; 7211 mat->cmap->mapping = l2g; 7212 } 7213 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7214 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7215 PetscFunctionReturn(0); 7216 } 7217 7218 /*@ 7219 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7220 7221 Logically Collective on Mat 7222 7223 Input Parameters: 7224 + mat - the matrix 7225 . fromRow - matrix from which to copy row block size 7226 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7227 7228 Level: developer 7229 7230 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7231 @*/ 7232 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7233 { 7234 PetscErrorCode ierr; 7235 7236 PetscFunctionBegin; 7237 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7238 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7239 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7240 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7241 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7242 PetscFunctionReturn(0); 7243 } 7244 7245 /*@ 7246 MatResidual - Default routine to calculate the residual. 7247 7248 Collective on Mat 7249 7250 Input Parameters: 7251 + mat - the matrix 7252 . b - the right-hand-side 7253 - x - the approximate solution 7254 7255 Output Parameter: 7256 . r - location to store the residual 7257 7258 Level: developer 7259 7260 .seealso: PCMGSetResidual() 7261 @*/ 7262 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7263 { 7264 PetscErrorCode ierr; 7265 7266 PetscFunctionBegin; 7267 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7268 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7269 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7270 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7271 PetscValidType(mat,1); 7272 MatCheckPreallocated(mat,1); 7273 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7274 if (!mat->ops->residual) { 7275 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7276 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7277 } else { 7278 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7279 } 7280 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7281 PetscFunctionReturn(0); 7282 } 7283 7284 /*@C 7285 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7286 7287 Collective on Mat 7288 7289 Input Parameters: 7290 + mat - the matrix 7291 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7292 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7293 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7294 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7295 always used. 7296 7297 Output Parameters: 7298 + n - number of rows in the (possibly compressed) matrix 7299 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7300 . ja - the column indices 7301 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7302 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7303 7304 Level: developer 7305 7306 Notes: 7307 You CANNOT change any of the ia[] or ja[] values. 7308 7309 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7310 7311 Fortran Notes: 7312 In Fortran use 7313 $ 7314 $ PetscInt ia(1), ja(1) 7315 $ PetscOffset iia, jja 7316 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7317 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7318 7319 or 7320 $ 7321 $ PetscInt, pointer :: ia(:),ja(:) 7322 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7323 $ ! Access the ith and jth entries via ia(i) and ja(j) 7324 7325 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7326 @*/ 7327 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7328 { 7329 PetscErrorCode ierr; 7330 7331 PetscFunctionBegin; 7332 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7333 PetscValidType(mat,1); 7334 PetscValidIntPointer(n,5); 7335 if (ia) PetscValidIntPointer(ia,6); 7336 if (ja) PetscValidIntPointer(ja,7); 7337 PetscValidIntPointer(done,8); 7338 MatCheckPreallocated(mat,1); 7339 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7340 else { 7341 *done = PETSC_TRUE; 7342 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7343 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7344 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7345 } 7346 PetscFunctionReturn(0); 7347 } 7348 7349 /*@C 7350 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7351 7352 Collective on Mat 7353 7354 Input Parameters: 7355 + mat - the matrix 7356 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7357 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7358 symmetrized 7359 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7360 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7361 always used. 7362 . n - number of columns in the (possibly compressed) matrix 7363 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7364 - ja - the row indices 7365 7366 Output Parameters: 7367 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7368 7369 Level: developer 7370 7371 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7372 @*/ 7373 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7374 { 7375 PetscErrorCode ierr; 7376 7377 PetscFunctionBegin; 7378 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7379 PetscValidType(mat,1); 7380 PetscValidIntPointer(n,4); 7381 if (ia) PetscValidIntPointer(ia,5); 7382 if (ja) PetscValidIntPointer(ja,6); 7383 PetscValidIntPointer(done,7); 7384 MatCheckPreallocated(mat,1); 7385 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7386 else { 7387 *done = PETSC_TRUE; 7388 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7389 } 7390 PetscFunctionReturn(0); 7391 } 7392 7393 /*@C 7394 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7395 MatGetRowIJ(). 7396 7397 Collective on Mat 7398 7399 Input Parameters: 7400 + mat - the matrix 7401 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7402 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7403 symmetrized 7404 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7405 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7406 always used. 7407 . n - size of (possibly compressed) matrix 7408 . ia - the row pointers 7409 - ja - the column indices 7410 7411 Output Parameters: 7412 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7413 7414 Note: 7415 This routine zeros out n, ia, and ja. This is to prevent accidental 7416 us of the array after it has been restored. If you pass NULL, it will 7417 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7418 7419 Level: developer 7420 7421 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7422 @*/ 7423 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7424 { 7425 PetscErrorCode ierr; 7426 7427 PetscFunctionBegin; 7428 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7429 PetscValidType(mat,1); 7430 if (ia) PetscValidIntPointer(ia,6); 7431 if (ja) PetscValidIntPointer(ja,7); 7432 PetscValidIntPointer(done,8); 7433 MatCheckPreallocated(mat,1); 7434 7435 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7436 else { 7437 *done = PETSC_TRUE; 7438 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7439 if (n) *n = 0; 7440 if (ia) *ia = NULL; 7441 if (ja) *ja = NULL; 7442 } 7443 PetscFunctionReturn(0); 7444 } 7445 7446 /*@C 7447 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7448 MatGetColumnIJ(). 7449 7450 Collective on Mat 7451 7452 Input Parameters: 7453 + mat - the matrix 7454 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7455 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7456 symmetrized 7457 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7458 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7459 always used. 7460 7461 Output Parameters: 7462 + n - size of (possibly compressed) matrix 7463 . ia - the column pointers 7464 . ja - the row indices 7465 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7466 7467 Level: developer 7468 7469 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7470 @*/ 7471 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7472 { 7473 PetscErrorCode ierr; 7474 7475 PetscFunctionBegin; 7476 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7477 PetscValidType(mat,1); 7478 if (ia) PetscValidIntPointer(ia,5); 7479 if (ja) PetscValidIntPointer(ja,6); 7480 PetscValidIntPointer(done,7); 7481 MatCheckPreallocated(mat,1); 7482 7483 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7484 else { 7485 *done = PETSC_TRUE; 7486 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7487 if (n) *n = 0; 7488 if (ia) *ia = NULL; 7489 if (ja) *ja = NULL; 7490 } 7491 PetscFunctionReturn(0); 7492 } 7493 7494 /*@C 7495 MatColoringPatch -Used inside matrix coloring routines that 7496 use MatGetRowIJ() and/or MatGetColumnIJ(). 7497 7498 Collective on Mat 7499 7500 Input Parameters: 7501 + mat - the matrix 7502 . ncolors - max color value 7503 . n - number of entries in colorarray 7504 - colorarray - array indicating color for each column 7505 7506 Output Parameters: 7507 . iscoloring - coloring generated using colorarray information 7508 7509 Level: developer 7510 7511 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7512 7513 @*/ 7514 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7515 { 7516 PetscErrorCode ierr; 7517 7518 PetscFunctionBegin; 7519 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7520 PetscValidType(mat,1); 7521 PetscValidIntPointer(colorarray,4); 7522 PetscValidPointer(iscoloring,5); 7523 MatCheckPreallocated(mat,1); 7524 7525 if (!mat->ops->coloringpatch) { 7526 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7527 } else { 7528 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7529 } 7530 PetscFunctionReturn(0); 7531 } 7532 7533 7534 /*@ 7535 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7536 7537 Logically Collective on Mat 7538 7539 Input Parameter: 7540 . mat - the factored matrix to be reset 7541 7542 Notes: 7543 This routine should be used only with factored matrices formed by in-place 7544 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7545 format). This option can save memory, for example, when solving nonlinear 7546 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7547 ILU(0) preconditioner. 7548 7549 Note that one can specify in-place ILU(0) factorization by calling 7550 .vb 7551 PCType(pc,PCILU); 7552 PCFactorSeUseInPlace(pc); 7553 .ve 7554 or by using the options -pc_type ilu -pc_factor_in_place 7555 7556 In-place factorization ILU(0) can also be used as a local 7557 solver for the blocks within the block Jacobi or additive Schwarz 7558 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7559 for details on setting local solver options. 7560 7561 Most users should employ the simplified KSP interface for linear solvers 7562 instead of working directly with matrix algebra routines such as this. 7563 See, e.g., KSPCreate(). 7564 7565 Level: developer 7566 7567 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7568 7569 @*/ 7570 PetscErrorCode MatSetUnfactored(Mat mat) 7571 { 7572 PetscErrorCode ierr; 7573 7574 PetscFunctionBegin; 7575 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7576 PetscValidType(mat,1); 7577 MatCheckPreallocated(mat,1); 7578 mat->factortype = MAT_FACTOR_NONE; 7579 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7580 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7581 PetscFunctionReturn(0); 7582 } 7583 7584 /*MC 7585 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7586 7587 Synopsis: 7588 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7589 7590 Not collective 7591 7592 Input Parameter: 7593 . x - matrix 7594 7595 Output Parameters: 7596 + xx_v - the Fortran90 pointer to the array 7597 - ierr - error code 7598 7599 Example of Usage: 7600 .vb 7601 PetscScalar, pointer xx_v(:,:) 7602 .... 7603 call MatDenseGetArrayF90(x,xx_v,ierr) 7604 a = xx_v(3) 7605 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7606 .ve 7607 7608 Level: advanced 7609 7610 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7611 7612 M*/ 7613 7614 /*MC 7615 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7616 accessed with MatDenseGetArrayF90(). 7617 7618 Synopsis: 7619 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7620 7621 Not collective 7622 7623 Input Parameters: 7624 + x - matrix 7625 - xx_v - the Fortran90 pointer to the array 7626 7627 Output Parameter: 7628 . ierr - error code 7629 7630 Example of Usage: 7631 .vb 7632 PetscScalar, pointer xx_v(:,:) 7633 .... 7634 call MatDenseGetArrayF90(x,xx_v,ierr) 7635 a = xx_v(3) 7636 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7637 .ve 7638 7639 Level: advanced 7640 7641 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7642 7643 M*/ 7644 7645 7646 /*MC 7647 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7648 7649 Synopsis: 7650 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7651 7652 Not collective 7653 7654 Input Parameter: 7655 . x - matrix 7656 7657 Output Parameters: 7658 + xx_v - the Fortran90 pointer to the array 7659 - ierr - error code 7660 7661 Example of Usage: 7662 .vb 7663 PetscScalar, pointer xx_v(:) 7664 .... 7665 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7666 a = xx_v(3) 7667 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7668 .ve 7669 7670 Level: advanced 7671 7672 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7673 7674 M*/ 7675 7676 /*MC 7677 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7678 accessed with MatSeqAIJGetArrayF90(). 7679 7680 Synopsis: 7681 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7682 7683 Not collective 7684 7685 Input Parameters: 7686 + x - matrix 7687 - xx_v - the Fortran90 pointer to the array 7688 7689 Output Parameter: 7690 . ierr - error code 7691 7692 Example of Usage: 7693 .vb 7694 PetscScalar, pointer xx_v(:) 7695 .... 7696 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7697 a = xx_v(3) 7698 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7699 .ve 7700 7701 Level: advanced 7702 7703 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7704 7705 M*/ 7706 7707 7708 /*@ 7709 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7710 as the original matrix. 7711 7712 Collective on Mat 7713 7714 Input Parameters: 7715 + mat - the original matrix 7716 . isrow - parallel IS containing the rows this processor should obtain 7717 . 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. 7718 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7719 7720 Output Parameter: 7721 . newmat - the new submatrix, of the same type as the old 7722 7723 Level: advanced 7724 7725 Notes: 7726 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7727 7728 Some matrix types place restrictions on the row and column indices, such 7729 as that they be sorted or that they be equal to each other. 7730 7731 The index sets may not have duplicate entries. 7732 7733 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7734 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 7735 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7736 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7737 you are finished using it. 7738 7739 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7740 the input matrix. 7741 7742 If iscol is NULL then all columns are obtained (not supported in Fortran). 7743 7744 Example usage: 7745 Consider the following 8x8 matrix with 34 non-zero values, that is 7746 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7747 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7748 as follows: 7749 7750 .vb 7751 1 2 0 | 0 3 0 | 0 4 7752 Proc0 0 5 6 | 7 0 0 | 8 0 7753 9 0 10 | 11 0 0 | 12 0 7754 ------------------------------------- 7755 13 0 14 | 15 16 17 | 0 0 7756 Proc1 0 18 0 | 19 20 21 | 0 0 7757 0 0 0 | 22 23 0 | 24 0 7758 ------------------------------------- 7759 Proc2 25 26 27 | 0 0 28 | 29 0 7760 30 0 0 | 31 32 33 | 0 34 7761 .ve 7762 7763 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7764 7765 .vb 7766 2 0 | 0 3 0 | 0 7767 Proc0 5 6 | 7 0 0 | 8 7768 ------------------------------- 7769 Proc1 18 0 | 19 20 21 | 0 7770 ------------------------------- 7771 Proc2 26 27 | 0 0 28 | 29 7772 0 0 | 31 32 33 | 0 7773 .ve 7774 7775 7776 .seealso: MatCreateSubMatrices(), MatCreateSubMatricesMPI(), MatCreateSubMatrixVirtual(), MatSubMatrixVirtualUpdate() 7777 @*/ 7778 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7779 { 7780 PetscErrorCode ierr; 7781 PetscMPIInt size; 7782 Mat *local; 7783 IS iscoltmp; 7784 PetscBool flg; 7785 7786 PetscFunctionBegin; 7787 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7788 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7789 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7790 PetscValidPointer(newmat,5); 7791 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7792 PetscValidType(mat,1); 7793 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7794 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 7795 7796 MatCheckPreallocated(mat,1); 7797 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 7798 7799 if (!iscol || isrow == iscol) { 7800 PetscBool stride; 7801 PetscMPIInt grabentirematrix = 0,grab; 7802 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 7803 if (stride) { 7804 PetscInt first,step,n,rstart,rend; 7805 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 7806 if (step == 1) { 7807 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 7808 if (rstart == first) { 7809 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 7810 if (n == rend-rstart) { 7811 grabentirematrix = 1; 7812 } 7813 } 7814 } 7815 } 7816 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 7817 if (grab) { 7818 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 7819 if (cll == MAT_INITIAL_MATRIX) { 7820 *newmat = mat; 7821 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 7822 } 7823 PetscFunctionReturn(0); 7824 } 7825 } 7826 7827 if (!iscol) { 7828 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 7829 } else { 7830 iscoltmp = iscol; 7831 } 7832 7833 /* if original matrix is on just one processor then use submatrix generated */ 7834 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 7835 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 7836 goto setproperties; 7837 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 7838 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 7839 *newmat = *local; 7840 ierr = PetscFree(local);CHKERRQ(ierr); 7841 goto setproperties; 7842 } else if (!mat->ops->createsubmatrix) { 7843 /* Create a new matrix type that implements the operation using the full matrix */ 7844 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7845 switch (cll) { 7846 case MAT_INITIAL_MATRIX: 7847 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 7848 break; 7849 case MAT_REUSE_MATRIX: 7850 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 7851 break; 7852 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 7853 } 7854 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7855 goto setproperties; 7856 } 7857 7858 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7859 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7860 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 7861 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7862 7863 setproperties: 7864 ierr = ISEqualUnsorted(isrow,iscoltmp,&flg);CHKERRQ(ierr); 7865 if (flg) { 7866 ierr = MatPropagateSymmetryOptions(mat,*newmat);CHKERRQ(ierr); 7867 } 7868 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7869 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 7870 PetscFunctionReturn(0); 7871 } 7872 7873 /*@ 7874 MatPropagateSymmetryOptions - Propagates symmetry options set on a matrix to another matrix 7875 7876 Not Collective 7877 7878 Input Parameters: 7879 + A - the matrix we wish to propagate options from 7880 - B - the matrix we wish to propagate options to 7881 7882 Level: beginner 7883 7884 Notes: Propagates the options associated to MAT_SYMMETRY_ETERNAL, MAT_STRUCTURALLY_SYMMETRIC, MAT_HERMITIAN, MAT_SPD and MAT_SYMMETRIC 7885 7886 .seealso: MatSetOption() 7887 @*/ 7888 PetscErrorCode MatPropagateSymmetryOptions(Mat A, Mat B) 7889 { 7890 PetscErrorCode ierr; 7891 7892 PetscFunctionBegin; 7893 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7894 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 7895 if (A->symmetric_eternal) { /* symmetric_eternal does not have a corresponding *set flag */ 7896 ierr = MatSetOption(B,MAT_SYMMETRY_ETERNAL,A->symmetric_eternal);CHKERRQ(ierr); 7897 } 7898 if (A->structurally_symmetric_set) { 7899 ierr = MatSetOption(B,MAT_STRUCTURALLY_SYMMETRIC,A->structurally_symmetric);CHKERRQ(ierr); 7900 } 7901 if (A->hermitian_set) { 7902 ierr = MatSetOption(B,MAT_HERMITIAN,A->hermitian);CHKERRQ(ierr); 7903 } 7904 if (A->spd_set) { 7905 ierr = MatSetOption(B,MAT_SPD,A->spd);CHKERRQ(ierr); 7906 } 7907 if (A->symmetric_set) { 7908 ierr = MatSetOption(B,MAT_SYMMETRIC,A->symmetric);CHKERRQ(ierr); 7909 } 7910 PetscFunctionReturn(0); 7911 } 7912 7913 /*@ 7914 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 7915 used during the assembly process to store values that belong to 7916 other processors. 7917 7918 Not Collective 7919 7920 Input Parameters: 7921 + mat - the matrix 7922 . size - the initial size of the stash. 7923 - bsize - the initial size of the block-stash(if used). 7924 7925 Options Database Keys: 7926 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 7927 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 7928 7929 Level: intermediate 7930 7931 Notes: 7932 The block-stash is used for values set with MatSetValuesBlocked() while 7933 the stash is used for values set with MatSetValues() 7934 7935 Run with the option -info and look for output of the form 7936 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 7937 to determine the appropriate value, MM, to use for size and 7938 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 7939 to determine the value, BMM to use for bsize 7940 7941 7942 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 7943 7944 @*/ 7945 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 7946 { 7947 PetscErrorCode ierr; 7948 7949 PetscFunctionBegin; 7950 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7951 PetscValidType(mat,1); 7952 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 7953 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 7954 PetscFunctionReturn(0); 7955 } 7956 7957 /*@ 7958 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 7959 the matrix 7960 7961 Neighbor-wise Collective on Mat 7962 7963 Input Parameters: 7964 + mat - the matrix 7965 . x,y - the vectors 7966 - w - where the result is stored 7967 7968 Level: intermediate 7969 7970 Notes: 7971 w may be the same vector as y. 7972 7973 This allows one to use either the restriction or interpolation (its transpose) 7974 matrix to do the interpolation 7975 7976 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 7977 7978 @*/ 7979 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 7980 { 7981 PetscErrorCode ierr; 7982 PetscInt M,N,Ny; 7983 7984 PetscFunctionBegin; 7985 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7986 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7987 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 7988 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 7989 PetscValidType(A,1); 7990 MatCheckPreallocated(A,1); 7991 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 7992 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 7993 if (M == Ny) { 7994 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 7995 } else { 7996 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 7997 } 7998 PetscFunctionReturn(0); 7999 } 8000 8001 /*@ 8002 MatInterpolate - y = A*x or A'*x depending on the shape of 8003 the matrix 8004 8005 Neighbor-wise Collective on Mat 8006 8007 Input Parameters: 8008 + mat - the matrix 8009 - x,y - the vectors 8010 8011 Level: intermediate 8012 8013 Notes: 8014 This allows one to use either the restriction or interpolation (its transpose) 8015 matrix to do the interpolation 8016 8017 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8018 8019 @*/ 8020 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8021 { 8022 PetscErrorCode ierr; 8023 PetscInt M,N,Ny; 8024 8025 PetscFunctionBegin; 8026 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8027 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8028 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8029 PetscValidType(A,1); 8030 MatCheckPreallocated(A,1); 8031 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8032 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8033 if (M == Ny) { 8034 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8035 } else { 8036 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8037 } 8038 PetscFunctionReturn(0); 8039 } 8040 8041 /*@ 8042 MatRestrict - y = A*x or A'*x 8043 8044 Neighbor-wise Collective on Mat 8045 8046 Input Parameters: 8047 + mat - the matrix 8048 - x,y - the vectors 8049 8050 Level: intermediate 8051 8052 Notes: 8053 This allows one to use either the restriction or interpolation (its transpose) 8054 matrix to do the restriction 8055 8056 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8057 8058 @*/ 8059 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8060 { 8061 PetscErrorCode ierr; 8062 PetscInt M,N,Ny; 8063 8064 PetscFunctionBegin; 8065 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8066 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8067 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8068 PetscValidType(A,1); 8069 MatCheckPreallocated(A,1); 8070 8071 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8072 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8073 if (M == Ny) { 8074 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8075 } else { 8076 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8077 } 8078 PetscFunctionReturn(0); 8079 } 8080 8081 /*@ 8082 MatGetNullSpace - retrieves the null space of a matrix. 8083 8084 Logically Collective on Mat 8085 8086 Input Parameters: 8087 + mat - the matrix 8088 - nullsp - the null space object 8089 8090 Level: developer 8091 8092 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8093 @*/ 8094 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8095 { 8096 PetscFunctionBegin; 8097 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8098 PetscValidPointer(nullsp,2); 8099 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8100 PetscFunctionReturn(0); 8101 } 8102 8103 /*@ 8104 MatSetNullSpace - attaches a null space to a matrix. 8105 8106 Logically Collective on Mat 8107 8108 Input Parameters: 8109 + mat - the matrix 8110 - nullsp - the null space object 8111 8112 Level: advanced 8113 8114 Notes: 8115 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8116 8117 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8118 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8119 8120 You can remove the null space by calling this routine with an nullsp of NULL 8121 8122 8123 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8124 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). 8125 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 8126 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 8127 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). 8128 8129 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8130 8131 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 8132 routine also automatically calls MatSetTransposeNullSpace(). 8133 8134 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8135 @*/ 8136 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8137 { 8138 PetscErrorCode ierr; 8139 8140 PetscFunctionBegin; 8141 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8142 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8143 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8144 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8145 mat->nullsp = nullsp; 8146 if (mat->symmetric_set && mat->symmetric) { 8147 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8148 } 8149 PetscFunctionReturn(0); 8150 } 8151 8152 /*@ 8153 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8154 8155 Logically Collective on Mat 8156 8157 Input Parameters: 8158 + mat - the matrix 8159 - nullsp - the null space object 8160 8161 Level: developer 8162 8163 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8164 @*/ 8165 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8166 { 8167 PetscFunctionBegin; 8168 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8169 PetscValidType(mat,1); 8170 PetscValidPointer(nullsp,2); 8171 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8172 PetscFunctionReturn(0); 8173 } 8174 8175 /*@ 8176 MatSetTransposeNullSpace - attaches a null space to a matrix. 8177 8178 Logically Collective on Mat 8179 8180 Input Parameters: 8181 + mat - the matrix 8182 - nullsp - the null space object 8183 8184 Level: advanced 8185 8186 Notes: 8187 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. 8188 You must also call MatSetNullSpace() 8189 8190 8191 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8192 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). 8193 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 8194 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 8195 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). 8196 8197 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8198 8199 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8200 @*/ 8201 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8202 { 8203 PetscErrorCode ierr; 8204 8205 PetscFunctionBegin; 8206 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8207 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8208 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8209 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8210 mat->transnullsp = nullsp; 8211 PetscFunctionReturn(0); 8212 } 8213 8214 /*@ 8215 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8216 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8217 8218 Logically Collective on Mat 8219 8220 Input Parameters: 8221 + mat - the matrix 8222 - nullsp - the null space object 8223 8224 Level: advanced 8225 8226 Notes: 8227 Overwrites any previous near null space that may have been attached 8228 8229 You can remove the null space by calling this routine with an nullsp of NULL 8230 8231 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8232 @*/ 8233 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8234 { 8235 PetscErrorCode ierr; 8236 8237 PetscFunctionBegin; 8238 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8239 PetscValidType(mat,1); 8240 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8241 MatCheckPreallocated(mat,1); 8242 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8243 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8244 mat->nearnullsp = nullsp; 8245 PetscFunctionReturn(0); 8246 } 8247 8248 /*@ 8249 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8250 8251 Not Collective 8252 8253 Input Parameters: 8254 . mat - the matrix 8255 8256 Output Parameters: 8257 . nullsp - the null space object, NULL if not set 8258 8259 Level: developer 8260 8261 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8262 @*/ 8263 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8264 { 8265 PetscFunctionBegin; 8266 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8267 PetscValidType(mat,1); 8268 PetscValidPointer(nullsp,2); 8269 MatCheckPreallocated(mat,1); 8270 *nullsp = mat->nearnullsp; 8271 PetscFunctionReturn(0); 8272 } 8273 8274 /*@C 8275 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8276 8277 Collective on Mat 8278 8279 Input Parameters: 8280 + mat - the matrix 8281 . row - row/column permutation 8282 . fill - expected fill factor >= 1.0 8283 - level - level of fill, for ICC(k) 8284 8285 Notes: 8286 Probably really in-place only when level of fill is zero, otherwise allocates 8287 new space to store factored matrix and deletes previous memory. 8288 8289 Most users should employ the simplified KSP interface for linear solvers 8290 instead of working directly with matrix algebra routines such as this. 8291 See, e.g., KSPCreate(). 8292 8293 Level: developer 8294 8295 8296 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8297 8298 Developer Note: fortran interface is not autogenerated as the f90 8299 interface defintion cannot be generated correctly [due to MatFactorInfo] 8300 8301 @*/ 8302 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8303 { 8304 PetscErrorCode ierr; 8305 8306 PetscFunctionBegin; 8307 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8308 PetscValidType(mat,1); 8309 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8310 PetscValidPointer(info,3); 8311 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8312 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8313 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8314 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8315 MatCheckPreallocated(mat,1); 8316 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8317 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8318 PetscFunctionReturn(0); 8319 } 8320 8321 /*@ 8322 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8323 ghosted ones. 8324 8325 Not Collective 8326 8327 Input Parameters: 8328 + mat - the matrix 8329 - diag = the diagonal values, including ghost ones 8330 8331 Level: developer 8332 8333 Notes: 8334 Works only for MPIAIJ and MPIBAIJ matrices 8335 8336 .seealso: MatDiagonalScale() 8337 @*/ 8338 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8339 { 8340 PetscErrorCode ierr; 8341 PetscMPIInt size; 8342 8343 PetscFunctionBegin; 8344 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8345 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8346 PetscValidType(mat,1); 8347 8348 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8349 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8350 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8351 if (size == 1) { 8352 PetscInt n,m; 8353 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8354 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8355 if (m == n) { 8356 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8357 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8358 } else { 8359 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8360 } 8361 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8362 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8363 PetscFunctionReturn(0); 8364 } 8365 8366 /*@ 8367 MatGetInertia - Gets the inertia from a factored matrix 8368 8369 Collective on Mat 8370 8371 Input Parameter: 8372 . mat - the matrix 8373 8374 Output Parameters: 8375 + nneg - number of negative eigenvalues 8376 . nzero - number of zero eigenvalues 8377 - npos - number of positive eigenvalues 8378 8379 Level: advanced 8380 8381 Notes: 8382 Matrix must have been factored by MatCholeskyFactor() 8383 8384 8385 @*/ 8386 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8387 { 8388 PetscErrorCode ierr; 8389 8390 PetscFunctionBegin; 8391 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8392 PetscValidType(mat,1); 8393 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8394 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8395 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8396 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8397 PetscFunctionReturn(0); 8398 } 8399 8400 /* ----------------------------------------------------------------*/ 8401 /*@C 8402 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8403 8404 Neighbor-wise Collective on Mats 8405 8406 Input Parameters: 8407 + mat - the factored matrix 8408 - b - the right-hand-side vectors 8409 8410 Output Parameter: 8411 . x - the result vectors 8412 8413 Notes: 8414 The vectors b and x cannot be the same. I.e., one cannot 8415 call MatSolves(A,x,x). 8416 8417 Notes: 8418 Most users should employ the simplified KSP interface for linear solvers 8419 instead of working directly with matrix algebra routines such as this. 8420 See, e.g., KSPCreate(). 8421 8422 Level: developer 8423 8424 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8425 @*/ 8426 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8427 { 8428 PetscErrorCode ierr; 8429 8430 PetscFunctionBegin; 8431 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8432 PetscValidType(mat,1); 8433 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8434 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8435 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8436 8437 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8438 MatCheckPreallocated(mat,1); 8439 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8440 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8441 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8442 PetscFunctionReturn(0); 8443 } 8444 8445 /*@ 8446 MatIsSymmetric - Test whether a matrix is symmetric 8447 8448 Collective on Mat 8449 8450 Input Parameter: 8451 + A - the matrix to test 8452 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8453 8454 Output Parameters: 8455 . flg - the result 8456 8457 Notes: 8458 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8459 8460 Level: intermediate 8461 8462 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8463 @*/ 8464 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8465 { 8466 PetscErrorCode ierr; 8467 8468 PetscFunctionBegin; 8469 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8470 PetscValidBoolPointer(flg,2); 8471 8472 if (!A->symmetric_set) { 8473 if (!A->ops->issymmetric) { 8474 MatType mattype; 8475 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8476 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 8477 } 8478 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8479 if (!tol) { 8480 ierr = MatSetOption(A,MAT_SYMMETRIC,*flg);CHKERRQ(ierr); 8481 } 8482 } else if (A->symmetric) { 8483 *flg = PETSC_TRUE; 8484 } else if (!tol) { 8485 *flg = PETSC_FALSE; 8486 } else { 8487 if (!A->ops->issymmetric) { 8488 MatType mattype; 8489 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8490 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for symmetric",mattype); 8491 } 8492 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8493 } 8494 PetscFunctionReturn(0); 8495 } 8496 8497 /*@ 8498 MatIsHermitian - Test whether a matrix is Hermitian 8499 8500 Collective on Mat 8501 8502 Input Parameter: 8503 + A - the matrix to test 8504 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8505 8506 Output Parameters: 8507 . flg - the result 8508 8509 Level: intermediate 8510 8511 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8512 MatIsSymmetricKnown(), MatIsSymmetric() 8513 @*/ 8514 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8515 { 8516 PetscErrorCode ierr; 8517 8518 PetscFunctionBegin; 8519 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8520 PetscValidBoolPointer(flg,2); 8521 8522 if (!A->hermitian_set) { 8523 if (!A->ops->ishermitian) { 8524 MatType mattype; 8525 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8526 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 8527 } 8528 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8529 if (!tol) { 8530 ierr = MatSetOption(A,MAT_HERMITIAN,*flg);CHKERRQ(ierr); 8531 } 8532 } else if (A->hermitian) { 8533 *flg = PETSC_TRUE; 8534 } else if (!tol) { 8535 *flg = PETSC_FALSE; 8536 } else { 8537 if (!A->ops->ishermitian) { 8538 MatType mattype; 8539 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8540 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type %s does not support checking for hermitian",mattype); 8541 } 8542 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8543 } 8544 PetscFunctionReturn(0); 8545 } 8546 8547 /*@ 8548 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8549 8550 Not Collective 8551 8552 Input Parameter: 8553 . A - the matrix to check 8554 8555 Output Parameters: 8556 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8557 - flg - the result 8558 8559 Level: advanced 8560 8561 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8562 if you want it explicitly checked 8563 8564 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8565 @*/ 8566 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8567 { 8568 PetscFunctionBegin; 8569 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8570 PetscValidPointer(set,2); 8571 PetscValidBoolPointer(flg,3); 8572 if (A->symmetric_set) { 8573 *set = PETSC_TRUE; 8574 *flg = A->symmetric; 8575 } else { 8576 *set = PETSC_FALSE; 8577 } 8578 PetscFunctionReturn(0); 8579 } 8580 8581 /*@ 8582 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8583 8584 Not Collective 8585 8586 Input Parameter: 8587 . A - the matrix to check 8588 8589 Output Parameters: 8590 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8591 - flg - the result 8592 8593 Level: advanced 8594 8595 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8596 if you want it explicitly checked 8597 8598 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8599 @*/ 8600 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8601 { 8602 PetscFunctionBegin; 8603 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8604 PetscValidPointer(set,2); 8605 PetscValidBoolPointer(flg,3); 8606 if (A->hermitian_set) { 8607 *set = PETSC_TRUE; 8608 *flg = A->hermitian; 8609 } else { 8610 *set = PETSC_FALSE; 8611 } 8612 PetscFunctionReturn(0); 8613 } 8614 8615 /*@ 8616 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8617 8618 Collective on Mat 8619 8620 Input Parameter: 8621 . A - the matrix to test 8622 8623 Output Parameters: 8624 . flg - the result 8625 8626 Level: intermediate 8627 8628 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8629 @*/ 8630 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8631 { 8632 PetscErrorCode ierr; 8633 8634 PetscFunctionBegin; 8635 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8636 PetscValidBoolPointer(flg,2); 8637 if (!A->structurally_symmetric_set) { 8638 if (!A->ops->isstructurallysymmetric) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type %s does not support checking for structural symmetric",((PetscObject)A)->type_name); 8639 ierr = (*A->ops->isstructurallysymmetric)(A,flg);CHKERRQ(ierr); 8640 ierr = MatSetOption(A,MAT_STRUCTURALLY_SYMMETRIC,*flg);CHKERRQ(ierr); 8641 } else *flg = A->structurally_symmetric; 8642 PetscFunctionReturn(0); 8643 } 8644 8645 /*@ 8646 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8647 to be communicated to other processors during the MatAssemblyBegin/End() process 8648 8649 Not collective 8650 8651 Input Parameter: 8652 . vec - the vector 8653 8654 Output Parameters: 8655 + nstash - the size of the stash 8656 . reallocs - the number of additional mallocs incurred. 8657 . bnstash - the size of the block stash 8658 - breallocs - the number of additional mallocs incurred.in the block stash 8659 8660 Level: advanced 8661 8662 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8663 8664 @*/ 8665 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8666 { 8667 PetscErrorCode ierr; 8668 8669 PetscFunctionBegin; 8670 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8671 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8672 PetscFunctionReturn(0); 8673 } 8674 8675 /*@C 8676 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8677 parallel layout 8678 8679 Collective on Mat 8680 8681 Input Parameter: 8682 . mat - the matrix 8683 8684 Output Parameter: 8685 + right - (optional) vector that the matrix can be multiplied against 8686 - left - (optional) vector that the matrix vector product can be stored in 8687 8688 Notes: 8689 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(). 8690 8691 Notes: 8692 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8693 8694 Level: advanced 8695 8696 .seealso: MatCreate(), VecDestroy() 8697 @*/ 8698 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8699 { 8700 PetscErrorCode ierr; 8701 8702 PetscFunctionBegin; 8703 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8704 PetscValidType(mat,1); 8705 if (mat->ops->getvecs) { 8706 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8707 } else { 8708 PetscInt rbs,cbs; 8709 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8710 if (right) { 8711 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8712 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8713 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8714 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8715 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 8716 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8717 } 8718 if (left) { 8719 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8720 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8721 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8722 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8723 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 8724 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8725 } 8726 } 8727 PetscFunctionReturn(0); 8728 } 8729 8730 /*@C 8731 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8732 with default values. 8733 8734 Not Collective 8735 8736 Input Parameters: 8737 . info - the MatFactorInfo data structure 8738 8739 8740 Notes: 8741 The solvers are generally used through the KSP and PC objects, for example 8742 PCLU, PCILU, PCCHOLESKY, PCICC 8743 8744 Level: developer 8745 8746 .seealso: MatFactorInfo 8747 8748 Developer Note: fortran interface is not autogenerated as the f90 8749 interface defintion cannot be generated correctly [due to MatFactorInfo] 8750 8751 @*/ 8752 8753 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8754 { 8755 PetscErrorCode ierr; 8756 8757 PetscFunctionBegin; 8758 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8759 PetscFunctionReturn(0); 8760 } 8761 8762 /*@ 8763 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 8764 8765 Collective on Mat 8766 8767 Input Parameters: 8768 + mat - the factored matrix 8769 - is - the index set defining the Schur indices (0-based) 8770 8771 Notes: 8772 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 8773 8774 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 8775 8776 Level: developer 8777 8778 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 8779 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 8780 8781 @*/ 8782 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 8783 { 8784 PetscErrorCode ierr,(*f)(Mat,IS); 8785 8786 PetscFunctionBegin; 8787 PetscValidType(mat,1); 8788 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8789 PetscValidType(is,2); 8790 PetscValidHeaderSpecific(is,IS_CLASSID,2); 8791 PetscCheckSameComm(mat,1,is,2); 8792 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 8793 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 8794 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"); 8795 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 8796 ierr = (*f)(mat,is);CHKERRQ(ierr); 8797 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 8798 PetscFunctionReturn(0); 8799 } 8800 8801 /*@ 8802 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 8803 8804 Logically Collective on Mat 8805 8806 Input Parameters: 8807 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 8808 . S - location where to return the Schur complement, can be NULL 8809 - status - the status of the Schur complement matrix, can be NULL 8810 8811 Notes: 8812 You must call MatFactorSetSchurIS() before calling this routine. 8813 8814 The routine provides a copy of the Schur matrix stored within the solver data structures. 8815 The caller must destroy the object when it is no longer needed. 8816 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 8817 8818 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) 8819 8820 Developer Notes: 8821 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 8822 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 8823 8824 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 8825 8826 Level: advanced 8827 8828 References: 8829 8830 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 8831 @*/ 8832 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 8833 { 8834 PetscErrorCode ierr; 8835 8836 PetscFunctionBegin; 8837 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8838 if (S) PetscValidPointer(S,2); 8839 if (status) PetscValidPointer(status,3); 8840 if (S) { 8841 PetscErrorCode (*f)(Mat,Mat*); 8842 8843 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 8844 if (f) { 8845 ierr = (*f)(F,S);CHKERRQ(ierr); 8846 } else { 8847 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 8848 } 8849 } 8850 if (status) *status = F->schur_status; 8851 PetscFunctionReturn(0); 8852 } 8853 8854 /*@ 8855 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 8856 8857 Logically Collective on Mat 8858 8859 Input Parameters: 8860 + F - the factored matrix obtained by calling MatGetFactor() 8861 . *S - location where to return the Schur complement, can be NULL 8862 - status - the status of the Schur complement matrix, can be NULL 8863 8864 Notes: 8865 You must call MatFactorSetSchurIS() before calling this routine. 8866 8867 Schur complement mode is currently implemented for sequential matrices. 8868 The routine returns a the Schur Complement stored within the data strutures of the solver. 8869 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 8870 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 8871 8872 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 8873 8874 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 8875 8876 Level: advanced 8877 8878 References: 8879 8880 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 8881 @*/ 8882 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 8883 { 8884 PetscFunctionBegin; 8885 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8886 if (S) PetscValidPointer(S,2); 8887 if (status) PetscValidPointer(status,3); 8888 if (S) *S = F->schur; 8889 if (status) *status = F->schur_status; 8890 PetscFunctionReturn(0); 8891 } 8892 8893 /*@ 8894 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 8895 8896 Logically Collective on Mat 8897 8898 Input Parameters: 8899 + F - the factored matrix obtained by calling MatGetFactor() 8900 . *S - location where the Schur complement is stored 8901 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 8902 8903 Notes: 8904 8905 Level: advanced 8906 8907 References: 8908 8909 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 8910 @*/ 8911 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 8912 { 8913 PetscErrorCode ierr; 8914 8915 PetscFunctionBegin; 8916 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8917 if (S) { 8918 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 8919 *S = NULL; 8920 } 8921 F->schur_status = status; 8922 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 8923 PetscFunctionReturn(0); 8924 } 8925 8926 /*@ 8927 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 8928 8929 Logically Collective on Mat 8930 8931 Input Parameters: 8932 + F - the factored matrix obtained by calling MatGetFactor() 8933 . rhs - location where the right hand side of the Schur complement system is stored 8934 - sol - location where the solution of the Schur complement system has to be returned 8935 8936 Notes: 8937 The sizes of the vectors should match the size of the Schur complement 8938 8939 Must be called after MatFactorSetSchurIS() 8940 8941 Level: advanced 8942 8943 References: 8944 8945 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 8946 @*/ 8947 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 8948 { 8949 PetscErrorCode ierr; 8950 8951 PetscFunctionBegin; 8952 PetscValidType(F,1); 8953 PetscValidType(rhs,2); 8954 PetscValidType(sol,3); 8955 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8956 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 8957 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 8958 PetscCheckSameComm(F,1,rhs,2); 8959 PetscCheckSameComm(F,1,sol,3); 8960 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 8961 switch (F->schur_status) { 8962 case MAT_FACTOR_SCHUR_FACTORED: 8963 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 8964 break; 8965 case MAT_FACTOR_SCHUR_INVERTED: 8966 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 8967 break; 8968 default: 8969 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 8970 break; 8971 } 8972 PetscFunctionReturn(0); 8973 } 8974 8975 /*@ 8976 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 8977 8978 Logically Collective on Mat 8979 8980 Input Parameters: 8981 + F - the factored matrix obtained by calling MatGetFactor() 8982 . rhs - location where the right hand side of the Schur complement system is stored 8983 - sol - location where the solution of the Schur complement system has to be returned 8984 8985 Notes: 8986 The sizes of the vectors should match the size of the Schur complement 8987 8988 Must be called after MatFactorSetSchurIS() 8989 8990 Level: advanced 8991 8992 References: 8993 8994 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 8995 @*/ 8996 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 8997 { 8998 PetscErrorCode ierr; 8999 9000 PetscFunctionBegin; 9001 PetscValidType(F,1); 9002 PetscValidType(rhs,2); 9003 PetscValidType(sol,3); 9004 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9005 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9006 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9007 PetscCheckSameComm(F,1,rhs,2); 9008 PetscCheckSameComm(F,1,sol,3); 9009 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9010 switch (F->schur_status) { 9011 case MAT_FACTOR_SCHUR_FACTORED: 9012 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 9013 break; 9014 case MAT_FACTOR_SCHUR_INVERTED: 9015 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 9016 break; 9017 default: 9018 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9019 break; 9020 } 9021 PetscFunctionReturn(0); 9022 } 9023 9024 /*@ 9025 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9026 9027 Logically Collective on Mat 9028 9029 Input Parameters: 9030 . F - the factored matrix obtained by calling MatGetFactor() 9031 9032 Notes: 9033 Must be called after MatFactorSetSchurIS(). 9034 9035 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9036 9037 Level: advanced 9038 9039 References: 9040 9041 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9042 @*/ 9043 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9044 { 9045 PetscErrorCode ierr; 9046 9047 PetscFunctionBegin; 9048 PetscValidType(F,1); 9049 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9050 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9051 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9052 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9053 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9054 PetscFunctionReturn(0); 9055 } 9056 9057 /*@ 9058 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9059 9060 Logically Collective on Mat 9061 9062 Input Parameters: 9063 . F - the factored matrix obtained by calling MatGetFactor() 9064 9065 Notes: 9066 Must be called after MatFactorSetSchurIS(). 9067 9068 Level: advanced 9069 9070 References: 9071 9072 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9073 @*/ 9074 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9075 { 9076 PetscErrorCode ierr; 9077 9078 PetscFunctionBegin; 9079 PetscValidType(F,1); 9080 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9081 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9082 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9083 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9084 PetscFunctionReturn(0); 9085 } 9086 9087 PetscErrorCode MatPtAP_Basic(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9088 { 9089 Mat AP; 9090 PetscErrorCode ierr; 9091 9092 PetscFunctionBegin; 9093 ierr = PetscInfo2(A,"Mat types %s and %s using basic PtAP\n",((PetscObject)A)->type_name,((PetscObject)P)->type_name);CHKERRQ(ierr); 9094 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AP);CHKERRQ(ierr); 9095 ierr = MatTransposeMatMult(P,AP,scall,fill,C);CHKERRQ(ierr); 9096 ierr = MatDestroy(&AP);CHKERRQ(ierr); 9097 PetscFunctionReturn(0); 9098 } 9099 9100 /*@ 9101 MatPtAP - Creates the matrix product C = P^T * A * P 9102 9103 Neighbor-wise Collective on Mat 9104 9105 Input Parameters: 9106 + A - the matrix 9107 . P - the projection matrix 9108 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9109 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9110 if the result is a dense matrix this is irrelevent 9111 9112 Output Parameters: 9113 . C - the product matrix 9114 9115 Notes: 9116 C will be created and must be destroyed by the user with MatDestroy(). 9117 9118 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9119 9120 Level: intermediate 9121 9122 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9123 @*/ 9124 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9125 { 9126 PetscErrorCode ierr; 9127 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9128 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9129 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9130 PetscBool sametype; 9131 9132 PetscFunctionBegin; 9133 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9134 PetscValidType(A,1); 9135 MatCheckPreallocated(A,1); 9136 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9137 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9138 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9139 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9140 PetscValidType(P,2); 9141 MatCheckPreallocated(P,2); 9142 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9143 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9144 9145 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); 9146 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); 9147 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9148 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9149 9150 if (scall == MAT_REUSE_MATRIX) { 9151 PetscValidPointer(*C,5); 9152 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9153 9154 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9155 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9156 if ((*C)->ops->ptapnumeric) { 9157 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9158 } else { 9159 ierr = MatPtAP_Basic(A,P,scall,fill,C); 9160 } 9161 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9162 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9163 PetscFunctionReturn(0); 9164 } 9165 9166 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9167 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9168 9169 fA = A->ops->ptap; 9170 fP = P->ops->ptap; 9171 ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr); 9172 if (fP == fA && sametype) { 9173 ptap = fA; 9174 } else { 9175 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9176 char ptapname[256]; 9177 ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr); 9178 ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9179 ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr); 9180 ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9181 ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9182 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9183 } 9184 9185 if (!ptap) ptap = MatPtAP_Basic; 9186 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9187 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9188 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9189 if (A->symmetric_set && A->symmetric) { 9190 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9191 } 9192 PetscFunctionReturn(0); 9193 } 9194 9195 /*@ 9196 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9197 9198 Neighbor-wise Collective on Mat 9199 9200 Input Parameters: 9201 + A - the matrix 9202 - P - the projection matrix 9203 9204 Output Parameters: 9205 . C - the product matrix 9206 9207 Notes: 9208 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9209 the user using MatDeatroy(). 9210 9211 This routine is currently only implemented for pairs of AIJ matrices and classes 9212 which inherit from AIJ. C will be of type MATAIJ. 9213 9214 Level: intermediate 9215 9216 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9217 @*/ 9218 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9219 { 9220 PetscErrorCode ierr; 9221 9222 PetscFunctionBegin; 9223 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9224 PetscValidType(A,1); 9225 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9226 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9227 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9228 PetscValidType(P,2); 9229 MatCheckPreallocated(P,2); 9230 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9231 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9232 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9233 PetscValidType(C,3); 9234 MatCheckPreallocated(C,3); 9235 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9236 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); 9237 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); 9238 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); 9239 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); 9240 MatCheckPreallocated(A,1); 9241 9242 if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first"); 9243 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9244 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9245 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9246 PetscFunctionReturn(0); 9247 } 9248 9249 /*@ 9250 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9251 9252 Neighbor-wise Collective on Mat 9253 9254 Input Parameters: 9255 + A - the matrix 9256 - P - the projection matrix 9257 9258 Output Parameters: 9259 . C - the (i,j) structure of the product matrix 9260 9261 Notes: 9262 C will be created and must be destroyed by the user with MatDestroy(). 9263 9264 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9265 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9266 this (i,j) structure by calling MatPtAPNumeric(). 9267 9268 Level: intermediate 9269 9270 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9271 @*/ 9272 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9273 { 9274 PetscErrorCode ierr; 9275 9276 PetscFunctionBegin; 9277 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9278 PetscValidType(A,1); 9279 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9280 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9281 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9282 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9283 PetscValidType(P,2); 9284 MatCheckPreallocated(P,2); 9285 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9286 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9287 PetscValidPointer(C,3); 9288 9289 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); 9290 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); 9291 MatCheckPreallocated(A,1); 9292 9293 if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name); 9294 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9295 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9296 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9297 9298 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9299 PetscFunctionReturn(0); 9300 } 9301 9302 /*@ 9303 MatRARt - Creates the matrix product C = R * A * R^T 9304 9305 Neighbor-wise Collective on Mat 9306 9307 Input Parameters: 9308 + A - the matrix 9309 . R - the projection matrix 9310 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9311 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9312 if the result is a dense matrix this is irrelevent 9313 9314 Output Parameters: 9315 . C - the product matrix 9316 9317 Notes: 9318 C will be created and must be destroyed by the user with MatDestroy(). 9319 9320 This routine is currently only implemented for pairs of AIJ matrices and classes 9321 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9322 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9323 We recommend using MatPtAP(). 9324 9325 Level: intermediate 9326 9327 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9328 @*/ 9329 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9330 { 9331 PetscErrorCode ierr; 9332 9333 PetscFunctionBegin; 9334 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9335 PetscValidType(A,1); 9336 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9337 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9338 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9339 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9340 PetscValidType(R,2); 9341 MatCheckPreallocated(R,2); 9342 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9343 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9344 PetscValidPointer(C,3); 9345 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); 9346 9347 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9348 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9349 MatCheckPreallocated(A,1); 9350 9351 if (!A->ops->rart) { 9352 Mat Rt; 9353 ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 9354 ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr); 9355 ierr = MatDestroy(&Rt);CHKERRQ(ierr); 9356 PetscFunctionReturn(0); 9357 } 9358 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9359 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9360 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9361 PetscFunctionReturn(0); 9362 } 9363 9364 /*@ 9365 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9366 9367 Neighbor-wise Collective on Mat 9368 9369 Input Parameters: 9370 + A - the matrix 9371 - R - the projection matrix 9372 9373 Output Parameters: 9374 . C - the product matrix 9375 9376 Notes: 9377 C must have been created by calling MatRARtSymbolic and must be destroyed by 9378 the user using MatDestroy(). 9379 9380 This routine is currently only implemented for pairs of AIJ matrices and classes 9381 which inherit from AIJ. C will be of type MATAIJ. 9382 9383 Level: intermediate 9384 9385 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9386 @*/ 9387 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9388 { 9389 PetscErrorCode ierr; 9390 9391 PetscFunctionBegin; 9392 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9393 PetscValidType(A,1); 9394 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9395 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9396 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9397 PetscValidType(R,2); 9398 MatCheckPreallocated(R,2); 9399 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9400 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9401 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9402 PetscValidType(C,3); 9403 MatCheckPreallocated(C,3); 9404 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9405 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); 9406 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); 9407 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); 9408 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); 9409 MatCheckPreallocated(A,1); 9410 9411 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9412 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9413 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9414 PetscFunctionReturn(0); 9415 } 9416 9417 /*@ 9418 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9419 9420 Neighbor-wise Collective on Mat 9421 9422 Input Parameters: 9423 + A - the matrix 9424 - R - the projection matrix 9425 9426 Output Parameters: 9427 . C - the (i,j) structure of the product matrix 9428 9429 Notes: 9430 C will be created and must be destroyed by the user with MatDestroy(). 9431 9432 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9433 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9434 this (i,j) structure by calling MatRARtNumeric(). 9435 9436 Level: intermediate 9437 9438 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9439 @*/ 9440 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9441 { 9442 PetscErrorCode ierr; 9443 9444 PetscFunctionBegin; 9445 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9446 PetscValidType(A,1); 9447 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9448 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9449 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9450 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9451 PetscValidType(R,2); 9452 MatCheckPreallocated(R,2); 9453 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9454 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9455 PetscValidPointer(C,3); 9456 9457 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); 9458 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); 9459 MatCheckPreallocated(A,1); 9460 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9461 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9462 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9463 9464 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9465 PetscFunctionReturn(0); 9466 } 9467 9468 /*@ 9469 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9470 9471 Neighbor-wise Collective on Mat 9472 9473 Input Parameters: 9474 + A - the left matrix 9475 . B - the right matrix 9476 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9477 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9478 if the result is a dense matrix this is irrelevent 9479 9480 Output Parameters: 9481 . C - the product matrix 9482 9483 Notes: 9484 Unless scall is MAT_REUSE_MATRIX C will be created. 9485 9486 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 9487 call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic() 9488 9489 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9490 actually needed. 9491 9492 If you have many matrices with the same non-zero structure to multiply, you 9493 should either 9494 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9495 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9496 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 9497 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9498 9499 Level: intermediate 9500 9501 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9502 @*/ 9503 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9504 { 9505 PetscErrorCode ierr; 9506 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9507 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9508 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9509 Mat T; 9510 PetscBool istrans; 9511 9512 PetscFunctionBegin; 9513 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9514 PetscValidType(A,1); 9515 MatCheckPreallocated(A,1); 9516 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9517 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9518 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9519 PetscValidType(B,2); 9520 MatCheckPreallocated(B,2); 9521 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9522 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9523 PetscValidPointer(C,3); 9524 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9525 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); 9526 ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9527 if (istrans) { 9528 ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 9529 ierr = MatTransposeMatMult(T,B,scall,fill,C);CHKERRQ(ierr); 9530 PetscFunctionReturn(0); 9531 } else { 9532 ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9533 if (istrans) { 9534 ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr); 9535 ierr = MatMatTransposeMult(A,T,scall,fill,C);CHKERRQ(ierr); 9536 PetscFunctionReturn(0); 9537 } 9538 } 9539 if (scall == MAT_REUSE_MATRIX) { 9540 PetscValidPointer(*C,5); 9541 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9542 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9543 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9544 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9545 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9546 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9547 PetscFunctionReturn(0); 9548 } 9549 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9550 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9551 9552 fA = A->ops->matmult; 9553 fB = B->ops->matmult; 9554 if (fB == fA && fB) mult = fB; 9555 else { 9556 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9557 char multname[256]; 9558 ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr); 9559 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9560 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9561 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9562 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9563 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9564 if (!mult) { 9565 ierr = PetscObjectQueryFunction((PetscObject)A,multname,&mult);CHKERRQ(ierr); 9566 } 9567 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); 9568 } 9569 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9570 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9571 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9572 PetscFunctionReturn(0); 9573 } 9574 9575 /*@ 9576 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9577 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9578 9579 Neighbor-wise Collective on Mat 9580 9581 Input Parameters: 9582 + A - the left matrix 9583 . B - the right matrix 9584 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9585 if C is a dense matrix this is irrelevent 9586 9587 Output Parameters: 9588 . C - the product matrix 9589 9590 Notes: 9591 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9592 actually needed. 9593 9594 This routine is currently implemented for 9595 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9596 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9597 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9598 9599 Level: intermediate 9600 9601 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, https://arxiv.org/abs/1006.4173 9602 We should incorporate them into PETSc. 9603 9604 .seealso: MatMatMult(), MatMatMultNumeric() 9605 @*/ 9606 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9607 { 9608 Mat T = NULL; 9609 PetscBool istrans; 9610 PetscErrorCode ierr; 9611 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9612 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9613 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9614 9615 PetscFunctionBegin; 9616 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9617 PetscValidType(A,1); 9618 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9619 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9620 9621 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9622 PetscValidType(B,2); 9623 MatCheckPreallocated(B,2); 9624 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9625 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9626 PetscValidPointer(C,3); 9627 9628 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); 9629 if (fill == PETSC_DEFAULT) fill = 2.0; 9630 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9631 MatCheckPreallocated(A,1); 9632 9633 Asymbolic = A->ops->matmultsymbolic; 9634 Bsymbolic = B->ops->matmultsymbolic; 9635 if (Asymbolic == Bsymbolic && Asymbolic) symbolic = Bsymbolic; 9636 else { /* dispatch based on the type of A and B */ 9637 char symbolicname[256]; 9638 ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9639 if (!istrans) { 9640 ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9641 ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9642 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9643 } else { 9644 ierr = PetscStrncpy(symbolicname,"MatTransposeMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9645 ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 9646 ierr = PetscStrlcat(symbolicname,((PetscObject)T)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9647 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9648 } 9649 ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9650 ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr); 9651 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9652 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); 9653 } 9654 ierr = PetscLogEventBegin(!T ? MAT_MatMultSymbolic : MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9655 *C = NULL; 9656 ierr = (*symbolic)(!T ? A : T,B,fill,C);CHKERRQ(ierr); 9657 ierr = PetscLogEventEnd(!T ? MAT_MatMultSymbolic : MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9658 PetscFunctionReturn(0); 9659 } 9660 9661 /*@ 9662 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9663 Call this routine after first calling MatMatMultSymbolic(). 9664 9665 Neighbor-wise Collective on Mat 9666 9667 Input Parameters: 9668 + A - the left matrix 9669 - B - the right matrix 9670 9671 Output Parameters: 9672 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9673 9674 Notes: 9675 C must have been created with MatMatMultSymbolic(). 9676 9677 This routine is currently implemented for 9678 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9679 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9680 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9681 9682 Level: intermediate 9683 9684 .seealso: MatMatMult(), MatMatMultSymbolic() 9685 @*/ 9686 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9687 { 9688 PetscErrorCode ierr; 9689 9690 PetscFunctionBegin; 9691 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr); 9692 PetscFunctionReturn(0); 9693 } 9694 9695 /*@ 9696 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9697 9698 Neighbor-wise Collective on Mat 9699 9700 Input Parameters: 9701 + A - the left matrix 9702 . B - the right matrix 9703 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9704 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9705 9706 Output Parameters: 9707 . C - the product matrix 9708 9709 Notes: 9710 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9711 9712 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9713 9714 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9715 actually needed. 9716 9717 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9718 and for pairs of MPIDense matrices. 9719 9720 Options Database Keys: 9721 . -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the 9722 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9723 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9724 9725 Level: intermediate 9726 9727 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9728 @*/ 9729 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9730 { 9731 PetscErrorCode ierr; 9732 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9733 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9734 Mat T; 9735 PetscBool istrans; 9736 9737 PetscFunctionBegin; 9738 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9739 PetscValidType(A,1); 9740 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9741 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9742 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9743 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9744 PetscValidType(B,2); 9745 MatCheckPreallocated(B,2); 9746 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9747 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9748 PetscValidPointer(C,3); 9749 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); 9750 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9751 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9752 MatCheckPreallocated(A,1); 9753 9754 ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9755 if (istrans) { 9756 ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr); 9757 ierr = MatMatMult(A,T,scall,fill,C);CHKERRQ(ierr); 9758 PetscFunctionReturn(0); 9759 } 9760 fA = A->ops->mattransposemult; 9761 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9762 fB = B->ops->mattransposemult; 9763 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9764 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); 9765 9766 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9767 if (scall == MAT_INITIAL_MATRIX) { 9768 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9769 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9770 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9771 } 9772 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9773 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 9774 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9775 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9776 PetscFunctionReturn(0); 9777 } 9778 9779 /*@ 9780 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9781 9782 Neighbor-wise Collective on Mat 9783 9784 Input Parameters: 9785 + A - the left matrix 9786 . B - the right matrix 9787 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9788 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9789 9790 Output Parameters: 9791 . C - the product matrix 9792 9793 Notes: 9794 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9795 9796 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9797 9798 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9799 actually needed. 9800 9801 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9802 which inherit from SeqAIJ. C will be of same type as the input matrices. 9803 9804 Level: intermediate 9805 9806 .seealso: MatMatMult(), MatMatTransposeMult(), MatPtAP() 9807 @*/ 9808 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9809 { 9810 PetscErrorCode ierr; 9811 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9812 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9813 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 9814 Mat T; 9815 PetscBool flg; 9816 9817 PetscFunctionBegin; 9818 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9819 PetscValidType(A,1); 9820 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9821 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9822 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9823 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9824 PetscValidType(B,2); 9825 MatCheckPreallocated(B,2); 9826 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9827 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9828 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); 9829 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9830 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9831 MatCheckPreallocated(A,1); 9832 9833 ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&flg);CHKERRQ(ierr); 9834 if (flg) { 9835 ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 9836 ierr = MatMatMult(T,B,scall,fill,C);CHKERRQ(ierr); 9837 PetscFunctionReturn(0); 9838 } 9839 if (scall == MAT_REUSE_MATRIX) { 9840 PetscValidPointer(*C,5); 9841 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9842 ierr = PetscObjectTypeCompareAny((PetscObject)*C,&flg,MATDENSE,MATSEQDENSE,MATMPIDENSE,"");CHKERRQ(ierr); 9843 if (flg) { 9844 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9845 ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9846 ierr = (*(*C)->ops->transposematmultnumeric)(A,B,*C);CHKERRQ(ierr); 9847 ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9848 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9849 PetscFunctionReturn(0); 9850 } 9851 } 9852 9853 fA = A->ops->transposematmult; 9854 fB = B->ops->transposematmult; 9855 if (fB == fA && fA) transposematmult = fA; 9856 else { 9857 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9858 char multname[256]; 9859 ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr); 9860 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9861 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9862 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9863 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9864 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 9865 if (!transposematmult) { 9866 ierr = PetscObjectQueryFunction((PetscObject)A,multname,&transposematmult);CHKERRQ(ierr); 9867 } 9868 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); 9869 } 9870 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9871 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 9872 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9873 PetscFunctionReturn(0); 9874 } 9875 9876 /*@ 9877 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9878 9879 Neighbor-wise Collective on Mat 9880 9881 Input Parameters: 9882 + A - the left matrix 9883 . B - the middle matrix 9884 . C - the right matrix 9885 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9886 - 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 9887 if the result is a dense matrix this is irrelevent 9888 9889 Output Parameters: 9890 . D - the product matrix 9891 9892 Notes: 9893 Unless scall is MAT_REUSE_MATRIX D will be created. 9894 9895 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9896 9897 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9898 actually needed. 9899 9900 If you have many matrices with the same non-zero structure to multiply, you 9901 should use MAT_REUSE_MATRIX in all calls but the first or 9902 9903 Level: intermediate 9904 9905 .seealso: MatMatMult, MatPtAP() 9906 @*/ 9907 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9908 { 9909 PetscErrorCode ierr; 9910 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9911 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9912 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9913 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9914 9915 PetscFunctionBegin; 9916 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9917 PetscValidType(A,1); 9918 MatCheckPreallocated(A,1); 9919 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9920 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9921 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9922 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9923 PetscValidType(B,2); 9924 MatCheckPreallocated(B,2); 9925 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9926 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9927 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9928 PetscValidPointer(C,3); 9929 MatCheckPreallocated(C,3); 9930 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9931 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9932 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); 9933 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); 9934 if (scall == MAT_REUSE_MATRIX) { 9935 PetscValidPointer(*D,6); 9936 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 9937 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9938 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9939 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9940 PetscFunctionReturn(0); 9941 } 9942 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9943 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9944 9945 fA = A->ops->matmatmult; 9946 fB = B->ops->matmatmult; 9947 fC = C->ops->matmatmult; 9948 if (fA == fB && fA == fC) { 9949 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9950 mult = fA; 9951 } else { 9952 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 9953 char multname[256]; 9954 ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr); 9955 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9956 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9957 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9958 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9959 ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr); 9960 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); 9961 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9962 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); 9963 } 9964 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9965 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9966 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9967 PetscFunctionReturn(0); 9968 } 9969 9970 /*@ 9971 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9972 9973 Collective on Mat 9974 9975 Input Parameters: 9976 + mat - the matrix 9977 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9978 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 9979 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9980 9981 Output Parameter: 9982 . matredundant - redundant matrix 9983 9984 Notes: 9985 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9986 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9987 9988 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 9989 calling it. 9990 9991 Level: advanced 9992 9993 9994 .seealso: MatDestroy() 9995 @*/ 9996 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 9997 { 9998 PetscErrorCode ierr; 9999 MPI_Comm comm; 10000 PetscMPIInt size; 10001 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10002 Mat_Redundant *redund=NULL; 10003 PetscSubcomm psubcomm=NULL; 10004 MPI_Comm subcomm_in=subcomm; 10005 Mat *matseq; 10006 IS isrow,iscol; 10007 PetscBool newsubcomm=PETSC_FALSE; 10008 10009 PetscFunctionBegin; 10010 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10011 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10012 PetscValidPointer(*matredundant,5); 10013 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10014 } 10015 10016 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10017 if (size == 1 || nsubcomm == 1) { 10018 if (reuse == MAT_INITIAL_MATRIX) { 10019 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 10020 } else { 10021 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"); 10022 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10023 } 10024 PetscFunctionReturn(0); 10025 } 10026 10027 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10028 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10029 MatCheckPreallocated(mat,1); 10030 10031 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10032 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10033 /* create psubcomm, then get subcomm */ 10034 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10035 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10036 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 10037 10038 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10039 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10040 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10041 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10042 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10043 newsubcomm = PETSC_TRUE; 10044 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10045 } 10046 10047 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10048 if (reuse == MAT_INITIAL_MATRIX) { 10049 mloc_sub = PETSC_DECIDE; 10050 nloc_sub = PETSC_DECIDE; 10051 if (bs < 1) { 10052 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10053 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 10054 } else { 10055 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10056 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 10057 } 10058 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10059 rstart = rend - mloc_sub; 10060 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10061 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10062 } else { /* reuse == MAT_REUSE_MATRIX */ 10063 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"); 10064 /* retrieve subcomm */ 10065 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10066 redund = (*matredundant)->redundant; 10067 isrow = redund->isrow; 10068 iscol = redund->iscol; 10069 matseq = redund->matseq; 10070 } 10071 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10072 10073 /* get matredundant over subcomm */ 10074 if (reuse == MAT_INITIAL_MATRIX) { 10075 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 10076 10077 /* create a supporting struct and attach it to C for reuse */ 10078 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10079 (*matredundant)->redundant = redund; 10080 redund->isrow = isrow; 10081 redund->iscol = iscol; 10082 redund->matseq = matseq; 10083 if (newsubcomm) { 10084 redund->subcomm = subcomm; 10085 } else { 10086 redund->subcomm = MPI_COMM_NULL; 10087 } 10088 } else { 10089 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10090 } 10091 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10092 PetscFunctionReturn(0); 10093 } 10094 10095 /*@C 10096 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10097 a given 'mat' object. Each submatrix can span multiple procs. 10098 10099 Collective on Mat 10100 10101 Input Parameters: 10102 + mat - the matrix 10103 . subcomm - the subcommunicator obtained by com_split(comm) 10104 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10105 10106 Output Parameter: 10107 . subMat - 'parallel submatrices each spans a given subcomm 10108 10109 Notes: 10110 The submatrix partition across processors is dictated by 'subComm' a 10111 communicator obtained by com_split(comm). The comm_split 10112 is not restriced to be grouped with consecutive original ranks. 10113 10114 Due the comm_split() usage, the parallel layout of the submatrices 10115 map directly to the layout of the original matrix [wrt the local 10116 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10117 into the 'DiagonalMat' of the subMat, hence it is used directly from 10118 the subMat. However the offDiagMat looses some columns - and this is 10119 reconstructed with MatSetValues() 10120 10121 Level: advanced 10122 10123 10124 .seealso: MatCreateSubMatrices() 10125 @*/ 10126 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10127 { 10128 PetscErrorCode ierr; 10129 PetscMPIInt commsize,subCommSize; 10130 10131 PetscFunctionBegin; 10132 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10133 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10134 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10135 10136 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"); 10137 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10138 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10139 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10140 PetscFunctionReturn(0); 10141 } 10142 10143 /*@ 10144 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10145 10146 Not Collective 10147 10148 Input Arguments: 10149 + mat - matrix to extract local submatrix from 10150 . isrow - local row indices for submatrix 10151 - iscol - local column indices for submatrix 10152 10153 Output Arguments: 10154 . submat - the submatrix 10155 10156 Level: intermediate 10157 10158 Notes: 10159 The submat should be returned with MatRestoreLocalSubMatrix(). 10160 10161 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10162 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10163 10164 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10165 MatSetValuesBlockedLocal() will also be implemented. 10166 10167 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10168 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10169 10170 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10171 @*/ 10172 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10173 { 10174 PetscErrorCode ierr; 10175 10176 PetscFunctionBegin; 10177 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10178 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10179 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10180 PetscCheckSameComm(isrow,2,iscol,3); 10181 PetscValidPointer(submat,4); 10182 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10183 10184 if (mat->ops->getlocalsubmatrix) { 10185 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10186 } else { 10187 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10188 } 10189 PetscFunctionReturn(0); 10190 } 10191 10192 /*@ 10193 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10194 10195 Not Collective 10196 10197 Input Arguments: 10198 mat - matrix to extract local submatrix from 10199 isrow - local row indices for submatrix 10200 iscol - local column indices for submatrix 10201 submat - the submatrix 10202 10203 Level: intermediate 10204 10205 .seealso: MatGetLocalSubMatrix() 10206 @*/ 10207 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10208 { 10209 PetscErrorCode ierr; 10210 10211 PetscFunctionBegin; 10212 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10213 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10214 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10215 PetscCheckSameComm(isrow,2,iscol,3); 10216 PetscValidPointer(submat,4); 10217 if (*submat) { 10218 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10219 } 10220 10221 if (mat->ops->restorelocalsubmatrix) { 10222 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10223 } else { 10224 ierr = MatDestroy(submat);CHKERRQ(ierr); 10225 } 10226 *submat = NULL; 10227 PetscFunctionReturn(0); 10228 } 10229 10230 /* --------------------------------------------------------*/ 10231 /*@ 10232 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10233 10234 Collective on Mat 10235 10236 Input Parameter: 10237 . mat - the matrix 10238 10239 Output Parameter: 10240 . is - if any rows have zero diagonals this contains the list of them 10241 10242 Level: developer 10243 10244 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10245 @*/ 10246 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10247 { 10248 PetscErrorCode ierr; 10249 10250 PetscFunctionBegin; 10251 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10252 PetscValidType(mat,1); 10253 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10254 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10255 10256 if (!mat->ops->findzerodiagonals) { 10257 Vec diag; 10258 const PetscScalar *a; 10259 PetscInt *rows; 10260 PetscInt rStart, rEnd, r, nrow = 0; 10261 10262 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10263 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10264 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10265 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10266 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10267 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10268 nrow = 0; 10269 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10270 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10271 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10272 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10273 } else { 10274 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10275 } 10276 PetscFunctionReturn(0); 10277 } 10278 10279 /*@ 10280 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10281 10282 Collective on Mat 10283 10284 Input Parameter: 10285 . mat - the matrix 10286 10287 Output Parameter: 10288 . is - contains the list of rows with off block diagonal entries 10289 10290 Level: developer 10291 10292 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10293 @*/ 10294 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10295 { 10296 PetscErrorCode ierr; 10297 10298 PetscFunctionBegin; 10299 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10300 PetscValidType(mat,1); 10301 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10302 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10303 10304 if (!mat->ops->findoffblockdiagonalentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s does not have a find off block diagonal entries defined",((PetscObject)mat)->type_name); 10305 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10306 PetscFunctionReturn(0); 10307 } 10308 10309 /*@C 10310 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10311 10312 Collective on Mat 10313 10314 Input Parameters: 10315 . mat - the matrix 10316 10317 Output Parameters: 10318 . values - the block inverses in column major order (FORTRAN-like) 10319 10320 Note: 10321 This routine is not available from Fortran. 10322 10323 Level: advanced 10324 10325 .seealso: MatInvertBockDiagonalMat 10326 @*/ 10327 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10328 { 10329 PetscErrorCode ierr; 10330 10331 PetscFunctionBegin; 10332 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10333 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10334 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10335 if (!mat->ops->invertblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type %s",((PetscObject)mat)->type_name); 10336 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10337 PetscFunctionReturn(0); 10338 } 10339 10340 /*@C 10341 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries. 10342 10343 Collective on Mat 10344 10345 Input Parameters: 10346 + mat - the matrix 10347 . nblocks - the number of blocks 10348 - bsizes - the size of each block 10349 10350 Output Parameters: 10351 . values - the block inverses in column major order (FORTRAN-like) 10352 10353 Note: 10354 This routine is not available from Fortran. 10355 10356 Level: advanced 10357 10358 .seealso: MatInvertBockDiagonal() 10359 @*/ 10360 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10361 { 10362 PetscErrorCode ierr; 10363 10364 PetscFunctionBegin; 10365 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10366 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10367 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10368 if (!mat->ops->invertvariableblockdiagonal) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for type",((PetscObject)mat)->type_name); 10369 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 10370 PetscFunctionReturn(0); 10371 } 10372 10373 /*@ 10374 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10375 10376 Collective on Mat 10377 10378 Input Parameters: 10379 . A - the matrix 10380 10381 Output Parameters: 10382 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10383 10384 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10385 10386 Level: advanced 10387 10388 .seealso: MatInvertBockDiagonal() 10389 @*/ 10390 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10391 { 10392 PetscErrorCode ierr; 10393 const PetscScalar *vals; 10394 PetscInt *dnnz; 10395 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10396 10397 PetscFunctionBegin; 10398 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10399 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10400 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10401 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10402 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10403 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10404 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10405 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10406 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10407 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10408 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10409 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10410 for (i = rstart/bs; i < rend/bs; i++) { 10411 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10412 } 10413 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10414 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10415 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10416 PetscFunctionReturn(0); 10417 } 10418 10419 /*@C 10420 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10421 via MatTransposeColoringCreate(). 10422 10423 Collective on MatTransposeColoring 10424 10425 Input Parameter: 10426 . c - coloring context 10427 10428 Level: intermediate 10429 10430 .seealso: MatTransposeColoringCreate() 10431 @*/ 10432 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10433 { 10434 PetscErrorCode ierr; 10435 MatTransposeColoring matcolor=*c; 10436 10437 PetscFunctionBegin; 10438 if (!matcolor) PetscFunctionReturn(0); 10439 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10440 10441 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10442 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10443 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10444 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10445 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10446 if (matcolor->brows>0) { 10447 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10448 } 10449 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10450 PetscFunctionReturn(0); 10451 } 10452 10453 /*@C 10454 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10455 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10456 MatTransposeColoring to sparse B. 10457 10458 Collective on MatTransposeColoring 10459 10460 Input Parameters: 10461 + B - sparse matrix B 10462 . Btdense - symbolic dense matrix B^T 10463 - coloring - coloring context created with MatTransposeColoringCreate() 10464 10465 Output Parameter: 10466 . Btdense - dense matrix B^T 10467 10468 Level: advanced 10469 10470 Notes: 10471 These are used internally for some implementations of MatRARt() 10472 10473 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10474 10475 @*/ 10476 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10477 { 10478 PetscErrorCode ierr; 10479 10480 PetscFunctionBegin; 10481 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10482 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10483 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10484 10485 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10486 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10487 PetscFunctionReturn(0); 10488 } 10489 10490 /*@C 10491 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10492 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10493 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10494 Csp from Cden. 10495 10496 Collective on MatTransposeColoring 10497 10498 Input Parameters: 10499 + coloring - coloring context created with MatTransposeColoringCreate() 10500 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10501 10502 Output Parameter: 10503 . Csp - sparse matrix 10504 10505 Level: advanced 10506 10507 Notes: 10508 These are used internally for some implementations of MatRARt() 10509 10510 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10511 10512 @*/ 10513 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10514 { 10515 PetscErrorCode ierr; 10516 10517 PetscFunctionBegin; 10518 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10519 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10520 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10521 10522 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10523 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10524 PetscFunctionReturn(0); 10525 } 10526 10527 /*@C 10528 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10529 10530 Collective on Mat 10531 10532 Input Parameters: 10533 + mat - the matrix product C 10534 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10535 10536 Output Parameter: 10537 . color - the new coloring context 10538 10539 Level: intermediate 10540 10541 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10542 MatTransColoringApplyDenToSp() 10543 @*/ 10544 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10545 { 10546 MatTransposeColoring c; 10547 MPI_Comm comm; 10548 PetscErrorCode ierr; 10549 10550 PetscFunctionBegin; 10551 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10552 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10553 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10554 10555 c->ctype = iscoloring->ctype; 10556 if (mat->ops->transposecoloringcreate) { 10557 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10558 } else SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for matrix type %s",((PetscObject)mat)->type_name); 10559 10560 *color = c; 10561 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10562 PetscFunctionReturn(0); 10563 } 10564 10565 /*@ 10566 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10567 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10568 same, otherwise it will be larger 10569 10570 Not Collective 10571 10572 Input Parameter: 10573 . A - the matrix 10574 10575 Output Parameter: 10576 . state - the current state 10577 10578 Notes: 10579 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10580 different matrices 10581 10582 Level: intermediate 10583 10584 @*/ 10585 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10586 { 10587 PetscFunctionBegin; 10588 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10589 *state = mat->nonzerostate; 10590 PetscFunctionReturn(0); 10591 } 10592 10593 /*@ 10594 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10595 matrices from each processor 10596 10597 Collective 10598 10599 Input Parameters: 10600 + comm - the communicators the parallel matrix will live on 10601 . seqmat - the input sequential matrices 10602 . n - number of local columns (or PETSC_DECIDE) 10603 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10604 10605 Output Parameter: 10606 . mpimat - the parallel matrix generated 10607 10608 Level: advanced 10609 10610 Notes: 10611 The number of columns of the matrix in EACH processor MUST be the same. 10612 10613 @*/ 10614 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10615 { 10616 PetscErrorCode ierr; 10617 10618 PetscFunctionBegin; 10619 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10620 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"); 10621 10622 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10623 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10624 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10625 PetscFunctionReturn(0); 10626 } 10627 10628 /*@ 10629 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10630 ranks' ownership ranges. 10631 10632 Collective on A 10633 10634 Input Parameters: 10635 + A - the matrix to create subdomains from 10636 - N - requested number of subdomains 10637 10638 10639 Output Parameters: 10640 + n - number of subdomains resulting on this rank 10641 - iss - IS list with indices of subdomains on this rank 10642 10643 Level: advanced 10644 10645 Notes: 10646 number of subdomains must be smaller than the communicator size 10647 @*/ 10648 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10649 { 10650 MPI_Comm comm,subcomm; 10651 PetscMPIInt size,rank,color; 10652 PetscInt rstart,rend,k; 10653 PetscErrorCode ierr; 10654 10655 PetscFunctionBegin; 10656 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10657 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10658 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10659 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); 10660 *n = 1; 10661 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10662 color = rank/k; 10663 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10664 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10665 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10666 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10667 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10668 PetscFunctionReturn(0); 10669 } 10670 10671 /*@ 10672 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10673 10674 If the interpolation and restriction operators are the same, uses MatPtAP. 10675 If they are not the same, use MatMatMatMult. 10676 10677 Once the coarse grid problem is constructed, correct for interpolation operators 10678 that are not of full rank, which can legitimately happen in the case of non-nested 10679 geometric multigrid. 10680 10681 Input Parameters: 10682 + restrct - restriction operator 10683 . dA - fine grid matrix 10684 . interpolate - interpolation operator 10685 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10686 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10687 10688 Output Parameters: 10689 . A - the Galerkin coarse matrix 10690 10691 Options Database Key: 10692 . -pc_mg_galerkin <both,pmat,mat,none> 10693 10694 Level: developer 10695 10696 .seealso: MatPtAP(), MatMatMatMult() 10697 @*/ 10698 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10699 { 10700 PetscErrorCode ierr; 10701 IS zerorows; 10702 Vec diag; 10703 10704 PetscFunctionBegin; 10705 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10706 /* Construct the coarse grid matrix */ 10707 if (interpolate == restrct) { 10708 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10709 } else { 10710 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10711 } 10712 10713 /* If the interpolation matrix is not of full rank, A will have zero rows. 10714 This can legitimately happen in the case of non-nested geometric multigrid. 10715 In that event, we set the rows of the matrix to the rows of the identity, 10716 ignoring the equations (as the RHS will also be zero). */ 10717 10718 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10719 10720 if (zerorows != NULL) { /* if there are any zero rows */ 10721 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10722 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10723 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10724 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10725 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10726 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10727 } 10728 PetscFunctionReturn(0); 10729 } 10730 10731 /*@C 10732 MatSetOperation - Allows user to set a matrix operation for any matrix type 10733 10734 Logically Collective on Mat 10735 10736 Input Parameters: 10737 + mat - the matrix 10738 . op - the name of the operation 10739 - f - the function that provides the operation 10740 10741 Level: developer 10742 10743 Usage: 10744 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10745 $ ierr = MatCreateXXX(comm,...&A); 10746 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10747 10748 Notes: 10749 See the file include/petscmat.h for a complete list of matrix 10750 operations, which all have the form MATOP_<OPERATION>, where 10751 <OPERATION> is the name (in all capital letters) of the 10752 user interface routine (e.g., MatMult() -> MATOP_MULT). 10753 10754 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10755 sequence as the usual matrix interface routines, since they 10756 are intended to be accessed via the usual matrix interface 10757 routines, e.g., 10758 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10759 10760 In particular each function MUST return an error code of 0 on success and 10761 nonzero on failure. 10762 10763 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10764 10765 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10766 @*/ 10767 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10768 { 10769 PetscFunctionBegin; 10770 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10771 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10772 mat->ops->viewnative = mat->ops->view; 10773 } 10774 (((void(**)(void))mat->ops)[op]) = f; 10775 PetscFunctionReturn(0); 10776 } 10777 10778 /*@C 10779 MatGetOperation - Gets a matrix operation for any matrix type. 10780 10781 Not Collective 10782 10783 Input Parameters: 10784 + mat - the matrix 10785 - op - the name of the operation 10786 10787 Output Parameter: 10788 . f - the function that provides the operation 10789 10790 Level: developer 10791 10792 Usage: 10793 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10794 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10795 10796 Notes: 10797 See the file include/petscmat.h for a complete list of matrix 10798 operations, which all have the form MATOP_<OPERATION>, where 10799 <OPERATION> is the name (in all capital letters) of the 10800 user interface routine (e.g., MatMult() -> MATOP_MULT). 10801 10802 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10803 10804 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 10805 @*/ 10806 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10807 { 10808 PetscFunctionBegin; 10809 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10810 *f = (((void (**)(void))mat->ops)[op]); 10811 PetscFunctionReturn(0); 10812 } 10813 10814 /*@ 10815 MatHasOperation - Determines whether the given matrix supports the particular 10816 operation. 10817 10818 Not Collective 10819 10820 Input Parameters: 10821 + mat - the matrix 10822 - op - the operation, for example, MATOP_GET_DIAGONAL 10823 10824 Output Parameter: 10825 . has - either PETSC_TRUE or PETSC_FALSE 10826 10827 Level: advanced 10828 10829 Notes: 10830 See the file include/petscmat.h for a complete list of matrix 10831 operations, which all have the form MATOP_<OPERATION>, where 10832 <OPERATION> is the name (in all capital letters) of the 10833 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10834 10835 .seealso: MatCreateShell() 10836 @*/ 10837 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10838 { 10839 PetscErrorCode ierr; 10840 10841 PetscFunctionBegin; 10842 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10843 PetscValidType(mat,1); 10844 PetscValidPointer(has,3); 10845 if (mat->ops->hasoperation) { 10846 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 10847 } else { 10848 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10849 else { 10850 *has = PETSC_FALSE; 10851 if (op == MATOP_CREATE_SUBMATRIX) { 10852 PetscMPIInt size; 10853 10854 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10855 if (size == 1) { 10856 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 10857 } 10858 } 10859 } 10860 } 10861 PetscFunctionReturn(0); 10862 } 10863 10864 /*@ 10865 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10866 of the matrix are congruent 10867 10868 Collective on mat 10869 10870 Input Parameters: 10871 . mat - the matrix 10872 10873 Output Parameter: 10874 . cong - either PETSC_TRUE or PETSC_FALSE 10875 10876 Level: beginner 10877 10878 Notes: 10879 10880 .seealso: MatCreate(), MatSetSizes() 10881 @*/ 10882 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 10883 { 10884 PetscErrorCode ierr; 10885 10886 PetscFunctionBegin; 10887 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10888 PetscValidType(mat,1); 10889 PetscValidPointer(cong,2); 10890 if (!mat->rmap || !mat->cmap) { 10891 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10892 PetscFunctionReturn(0); 10893 } 10894 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10895 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 10896 if (*cong) mat->congruentlayouts = 1; 10897 else mat->congruentlayouts = 0; 10898 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10899 PetscFunctionReturn(0); 10900 } 10901 10902 /*@ 10903 MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse, 10904 e.g., matrx product of MatPtAP. 10905 10906 Collective on mat 10907 10908 Input Parameters: 10909 . mat - the matrix 10910 10911 Output Parameter: 10912 . mat - the matrix with intermediate data structures released 10913 10914 Level: advanced 10915 10916 Notes: 10917 10918 .seealso: MatPtAP(), MatMatMult() 10919 @*/ 10920 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat) 10921 { 10922 PetscErrorCode ierr; 10923 10924 PetscFunctionBegin; 10925 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10926 PetscValidType(mat,1); 10927 if (mat->ops->freeintermediatedatastructures) { 10928 ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr); 10929 } 10930 PetscFunctionReturn(0); 10931 } 10932