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