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