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