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