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