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