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