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