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