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