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 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) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type); 4288 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4289 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); 4290 4291 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4292 PetscFunctionReturn(0); 4293 } 4294 4295 #undef __FUNCT__ 4296 #define __FUNCT__ "MatGetFactorAvailable" 4297 /*@C 4298 MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type 4299 4300 Not Collective 4301 4302 Input Parameters: 4303 + mat - the matrix 4304 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4305 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4306 4307 Output Parameter: 4308 . flg - PETSC_TRUE if the factorization is available 4309 4310 Notes: 4311 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4312 such as pastix, superlu, mumps etc. 4313 4314 PETSc must have been ./configure to use the external solver, using the option --download-package 4315 4316 Level: intermediate 4317 4318 .seealso: MatCopy(), MatDuplicate(), MatGetFactor() 4319 @*/ 4320 PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool *flg) 4321 { 4322 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4323 4324 PetscFunctionBegin; 4325 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4326 PetscValidType(mat,1); 4327 4328 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4329 MatCheckPreallocated(mat,1); 4330 4331 *flg = PETSC_FALSE; 4332 ierr = MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4333 if (gconv) { 4334 *flg = PETSC_TRUE; 4335 } 4336 PetscFunctionReturn(0); 4337 } 4338 4339 #include <petscdmtypes.h> 4340 4341 #undef __FUNCT__ 4342 #define __FUNCT__ "MatDuplicate" 4343 /*@ 4344 MatDuplicate - Duplicates a matrix including the non-zero structure. 4345 4346 Collective on Mat 4347 4348 Input Parameters: 4349 + mat - the matrix 4350 - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix 4351 MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them. 4352 4353 Output Parameter: 4354 . M - pointer to place new matrix 4355 4356 Level: intermediate 4357 4358 Concepts: matrices^duplicating 4359 4360 Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4361 4362 .seealso: MatCopy(), MatConvert() 4363 @*/ 4364 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4365 { 4366 PetscErrorCode ierr; 4367 Mat B; 4368 PetscInt i; 4369 DM dm; 4370 4371 PetscFunctionBegin; 4372 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4373 PetscValidType(mat,1); 4374 PetscValidPointer(M,3); 4375 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4376 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4377 MatCheckPreallocated(mat,1); 4378 4379 *M = 0; 4380 if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type"); 4381 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4382 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4383 B = *M; 4384 4385 B->stencil.dim = mat->stencil.dim; 4386 B->stencil.noc = mat->stencil.noc; 4387 for (i=0; i<=mat->stencil.dim; i++) { 4388 B->stencil.dims[i] = mat->stencil.dims[i]; 4389 B->stencil.starts[i] = mat->stencil.starts[i]; 4390 } 4391 4392 B->nooffproczerorows = mat->nooffproczerorows; 4393 B->nooffprocentries = mat->nooffprocentries; 4394 4395 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr); 4396 if (dm) { 4397 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 4398 } 4399 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4400 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4401 PetscFunctionReturn(0); 4402 } 4403 4404 #undef __FUNCT__ 4405 #define __FUNCT__ "MatGetDiagonal" 4406 /*@ 4407 MatGetDiagonal - Gets the diagonal of a matrix. 4408 4409 Logically Collective on Mat and Vec 4410 4411 Input Parameters: 4412 + mat - the matrix 4413 - v - the vector for storing the diagonal 4414 4415 Output Parameter: 4416 . v - the diagonal of the matrix 4417 4418 Level: intermediate 4419 4420 Note: 4421 Currently only correct in parallel for square matrices. 4422 4423 Concepts: matrices^accessing diagonals 4424 4425 .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs() 4426 @*/ 4427 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4428 { 4429 PetscErrorCode ierr; 4430 4431 PetscFunctionBegin; 4432 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4433 PetscValidType(mat,1); 4434 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4435 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4436 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4437 MatCheckPreallocated(mat,1); 4438 4439 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4440 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4441 PetscFunctionReturn(0); 4442 } 4443 4444 #undef __FUNCT__ 4445 #define __FUNCT__ "MatGetRowMin" 4446 /*@C 4447 MatGetRowMin - Gets the minimum value (of the real part) of each 4448 row of the matrix 4449 4450 Logically Collective on Mat and Vec 4451 4452 Input Parameters: 4453 . mat - the matrix 4454 4455 Output Parameter: 4456 + v - the vector for storing the maximums 4457 - idx - the indices of the column found for each row (optional) 4458 4459 Level: intermediate 4460 4461 Notes: The result of this call are the same as if one converted the matrix to dense format 4462 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4463 4464 This code is only implemented for a couple of matrix formats. 4465 4466 Concepts: matrices^getting row maximums 4467 4468 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), 4469 MatGetRowMax() 4470 @*/ 4471 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4472 { 4473 PetscErrorCode ierr; 4474 4475 PetscFunctionBegin; 4476 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4477 PetscValidType(mat,1); 4478 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4479 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4480 if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4481 MatCheckPreallocated(mat,1); 4482 4483 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4484 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4485 PetscFunctionReturn(0); 4486 } 4487 4488 #undef __FUNCT__ 4489 #define __FUNCT__ "MatGetRowMinAbs" 4490 /*@C 4491 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4492 row of the matrix 4493 4494 Logically Collective on Mat and Vec 4495 4496 Input Parameters: 4497 . mat - the matrix 4498 4499 Output Parameter: 4500 + v - the vector for storing the minimums 4501 - idx - the indices of the column found for each row (or NULL if not needed) 4502 4503 Level: intermediate 4504 4505 Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that 4506 row is 0 (the first column). 4507 4508 This code is only implemented for a couple of matrix formats. 4509 4510 Concepts: matrices^getting row maximums 4511 4512 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4513 @*/ 4514 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4515 { 4516 PetscErrorCode ierr; 4517 4518 PetscFunctionBegin; 4519 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4520 PetscValidType(mat,1); 4521 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4522 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4523 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4524 MatCheckPreallocated(mat,1); 4525 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4526 4527 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4528 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4529 PetscFunctionReturn(0); 4530 } 4531 4532 #undef __FUNCT__ 4533 #define __FUNCT__ "MatGetRowMax" 4534 /*@C 4535 MatGetRowMax - Gets the maximum value (of the real part) of each 4536 row of the matrix 4537 4538 Logically Collective on Mat and Vec 4539 4540 Input Parameters: 4541 . mat - the matrix 4542 4543 Output Parameter: 4544 + v - the vector for storing the maximums 4545 - idx - the indices of the column found for each row (optional) 4546 4547 Level: intermediate 4548 4549 Notes: The result of this call are the same as if one converted the matrix to dense format 4550 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4551 4552 This code is only implemented for a couple of matrix formats. 4553 4554 Concepts: matrices^getting row maximums 4555 4556 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4557 @*/ 4558 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4559 { 4560 PetscErrorCode ierr; 4561 4562 PetscFunctionBegin; 4563 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4564 PetscValidType(mat,1); 4565 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4566 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4567 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4568 MatCheckPreallocated(mat,1); 4569 4570 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4571 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4572 PetscFunctionReturn(0); 4573 } 4574 4575 #undef __FUNCT__ 4576 #define __FUNCT__ "MatGetRowMaxAbs" 4577 /*@C 4578 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4579 row of the matrix 4580 4581 Logically Collective on Mat and Vec 4582 4583 Input Parameters: 4584 . mat - the matrix 4585 4586 Output Parameter: 4587 + v - the vector for storing the maximums 4588 - idx - the indices of the column found for each row (or NULL if not needed) 4589 4590 Level: intermediate 4591 4592 Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that 4593 row is 0 (the first column). 4594 4595 This code is only implemented for a couple of matrix formats. 4596 4597 Concepts: matrices^getting row maximums 4598 4599 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin() 4600 @*/ 4601 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4602 { 4603 PetscErrorCode ierr; 4604 4605 PetscFunctionBegin; 4606 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4607 PetscValidType(mat,1); 4608 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4609 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4610 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4611 MatCheckPreallocated(mat,1); 4612 if (idx) {ierr = PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr);} 4613 4614 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4615 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4616 PetscFunctionReturn(0); 4617 } 4618 4619 #undef __FUNCT__ 4620 #define __FUNCT__ "MatGetRowSum" 4621 /*@ 4622 MatGetRowSum - Gets the sum of each row of the matrix 4623 4624 Logically Collective on Mat and Vec 4625 4626 Input Parameters: 4627 . mat - the matrix 4628 4629 Output Parameter: 4630 . v - the vector for storing the sum of rows 4631 4632 Level: intermediate 4633 4634 Notes: This code is slow since it is not currently specialized for different formats 4635 4636 Concepts: matrices^getting row sums 4637 4638 .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin() 4639 @*/ 4640 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4641 { 4642 PetscInt start = 0, end = 0, row; 4643 PetscScalar *array; 4644 PetscErrorCode ierr; 4645 4646 PetscFunctionBegin; 4647 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4648 PetscValidType(mat,1); 4649 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4650 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4651 MatCheckPreallocated(mat,1); 4652 ierr = MatGetOwnershipRange(mat, &start, &end);CHKERRQ(ierr); 4653 ierr = VecGetArray(v, &array);CHKERRQ(ierr); 4654 for (row = start; row < end; ++row) { 4655 PetscInt ncols, col; 4656 const PetscInt *cols; 4657 const PetscScalar *vals; 4658 4659 array[row - start] = 0.0; 4660 4661 ierr = MatGetRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr); 4662 for (col = 0; col < ncols; col++) { 4663 array[row - start] += vals[col]; 4664 } 4665 ierr = MatRestoreRow(mat, row, &ncols, &cols, &vals);CHKERRQ(ierr); 4666 } 4667 ierr = VecRestoreArray(v, &array);CHKERRQ(ierr); 4668 ierr = PetscObjectStateIncrease((PetscObject) v);CHKERRQ(ierr); 4669 PetscFunctionReturn(0); 4670 } 4671 4672 #undef __FUNCT__ 4673 #define __FUNCT__ "MatTranspose" 4674 /*@ 4675 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4676 4677 Collective on Mat 4678 4679 Input Parameter: 4680 + mat - the matrix to transpose 4681 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 4682 4683 Output Parameters: 4684 . B - the transpose 4685 4686 Notes: 4687 If you pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat); 4688 4689 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4690 4691 Level: intermediate 4692 4693 Concepts: matrices^transposing 4694 4695 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4696 @*/ 4697 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4698 { 4699 PetscErrorCode ierr; 4700 4701 PetscFunctionBegin; 4702 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4703 PetscValidType(mat,1); 4704 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4705 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4706 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4707 MatCheckPreallocated(mat,1); 4708 4709 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4710 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 4711 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4712 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 4713 PetscFunctionReturn(0); 4714 } 4715 4716 #undef __FUNCT__ 4717 #define __FUNCT__ "MatIsTranspose" 4718 /*@ 4719 MatIsTranspose - Test whether a matrix is another one's transpose, 4720 or its own, in which case it tests symmetry. 4721 4722 Collective on Mat 4723 4724 Input Parameter: 4725 + A - the matrix to test 4726 - B - the matrix to test against, this can equal the first parameter 4727 4728 Output Parameters: 4729 . flg - the result 4730 4731 Notes: 4732 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4733 has a running time of the order of the number of nonzeros; the parallel 4734 test involves parallel copies of the block-offdiagonal parts of the matrix. 4735 4736 Level: intermediate 4737 4738 Concepts: matrices^transposing, matrix^symmetry 4739 4740 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 4741 @*/ 4742 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4743 { 4744 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4745 4746 PetscFunctionBegin; 4747 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4748 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4749 PetscValidPointer(flg,3); 4750 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 4751 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 4752 *flg = PETSC_FALSE; 4753 if (f && g) { 4754 if (f == g) { 4755 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4756 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 4757 } else { 4758 MatType mattype; 4759 if (!f) { 4760 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 4761 } else { 4762 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 4763 } 4764 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype); 4765 } 4766 PetscFunctionReturn(0); 4767 } 4768 4769 #undef __FUNCT__ 4770 #define __FUNCT__ "MatHermitianTranspose" 4771 /*@ 4772 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 4773 4774 Collective on Mat 4775 4776 Input Parameter: 4777 + mat - the matrix to transpose and complex conjugate 4778 - reuse - store the transpose matrix in the provided B 4779 4780 Output Parameters: 4781 . B - the Hermitian 4782 4783 Notes: 4784 If you pass in &mat for B the Hermitian will be done in place 4785 4786 Level: intermediate 4787 4788 Concepts: matrices^transposing, complex conjugatex 4789 4790 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4791 @*/ 4792 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 4793 { 4794 PetscErrorCode ierr; 4795 4796 PetscFunctionBegin; 4797 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 4798 #if defined(PETSC_USE_COMPLEX) 4799 ierr = MatConjugate(*B);CHKERRQ(ierr); 4800 #endif 4801 PetscFunctionReturn(0); 4802 } 4803 4804 #undef __FUNCT__ 4805 #define __FUNCT__ "MatIsHermitianTranspose" 4806 /*@ 4807 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 4808 4809 Collective on Mat 4810 4811 Input Parameter: 4812 + A - the matrix to test 4813 - B - the matrix to test against, this can equal the first parameter 4814 4815 Output Parameters: 4816 . flg - the result 4817 4818 Notes: 4819 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4820 has a running time of the order of the number of nonzeros; the parallel 4821 test involves parallel copies of the block-offdiagonal parts of the matrix. 4822 4823 Level: intermediate 4824 4825 Concepts: matrices^transposing, matrix^symmetry 4826 4827 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 4828 @*/ 4829 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4830 { 4831 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4832 4833 PetscFunctionBegin; 4834 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4835 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4836 PetscValidPointer(flg,3); 4837 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 4838 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 4839 if (f && g) { 4840 if (f==g) { 4841 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4842 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 4843 } 4844 PetscFunctionReturn(0); 4845 } 4846 4847 #undef __FUNCT__ 4848 #define __FUNCT__ "MatPermute" 4849 /*@ 4850 MatPermute - Creates a new matrix with rows and columns permuted from the 4851 original. 4852 4853 Collective on Mat 4854 4855 Input Parameters: 4856 + mat - the matrix to permute 4857 . row - row permutation, each processor supplies only the permutation for its rows 4858 - col - column permutation, each processor supplies only the permutation for its columns 4859 4860 Output Parameters: 4861 . B - the permuted matrix 4862 4863 Level: advanced 4864 4865 Note: 4866 The index sets map from row/col of permuted matrix to row/col of original matrix. 4867 The index sets should be on the same communicator as Mat and have the same local sizes. 4868 4869 Concepts: matrices^permuting 4870 4871 .seealso: MatGetOrdering(), ISAllGather() 4872 4873 @*/ 4874 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 4875 { 4876 PetscErrorCode ierr; 4877 4878 PetscFunctionBegin; 4879 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4880 PetscValidType(mat,1); 4881 PetscValidHeaderSpecific(row,IS_CLASSID,2); 4882 PetscValidHeaderSpecific(col,IS_CLASSID,3); 4883 PetscValidPointer(B,4); 4884 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4885 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4886 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 4887 MatCheckPreallocated(mat,1); 4888 4889 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 4890 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 4891 PetscFunctionReturn(0); 4892 } 4893 4894 #undef __FUNCT__ 4895 #define __FUNCT__ "MatEqual" 4896 /*@ 4897 MatEqual - Compares two matrices. 4898 4899 Collective on Mat 4900 4901 Input Parameters: 4902 + A - the first matrix 4903 - B - the second matrix 4904 4905 Output Parameter: 4906 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 4907 4908 Level: intermediate 4909 4910 Concepts: matrices^equality between 4911 @*/ 4912 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 4913 { 4914 PetscErrorCode ierr; 4915 4916 PetscFunctionBegin; 4917 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4918 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4919 PetscValidType(A,1); 4920 PetscValidType(B,2); 4921 PetscValidIntPointer(flg,3); 4922 PetscCheckSameComm(A,1,B,2); 4923 MatCheckPreallocated(B,2); 4924 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4925 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4926 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); 4927 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 4928 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 4929 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); 4930 MatCheckPreallocated(A,1); 4931 4932 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 4933 PetscFunctionReturn(0); 4934 } 4935 4936 #undef __FUNCT__ 4937 #define __FUNCT__ "MatDiagonalScale" 4938 /*@ 4939 MatDiagonalScale - Scales a matrix on the left and right by diagonal 4940 matrices that are stored as vectors. Either of the two scaling 4941 matrices can be NULL. 4942 4943 Collective on Mat 4944 4945 Input Parameters: 4946 + mat - the matrix to be scaled 4947 . l - the left scaling vector (or NULL) 4948 - r - the right scaling vector (or NULL) 4949 4950 Notes: 4951 MatDiagonalScale() computes A = LAR, where 4952 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 4953 The L scales the rows of the matrix, the R scales the columns of the matrix. 4954 4955 Level: intermediate 4956 4957 Concepts: matrices^diagonal scaling 4958 Concepts: diagonal scaling of matrices 4959 4960 .seealso: MatScale() 4961 @*/ 4962 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 4963 { 4964 PetscErrorCode ierr; 4965 4966 PetscFunctionBegin; 4967 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4968 PetscValidType(mat,1); 4969 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4970 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 4971 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 4972 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4973 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4974 MatCheckPreallocated(mat,1); 4975 4976 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 4977 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 4978 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 4979 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 4980 #if defined(PETSC_HAVE_CUSP) 4981 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 4982 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 4983 } 4984 #elif defined(PETSC_HAVE_VIENNACL) 4985 if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) { 4986 mat->valid_GPU_matrix = PETSC_VIENNACL_CPU; 4987 } 4988 #elif defined(PETSC_HAVE_VECCUDA) 4989 if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) { 4990 mat->valid_GPU_matrix = PETSC_CUDA_CPU; 4991 } 4992 #endif 4993 PetscFunctionReturn(0); 4994 } 4995 4996 #undef __FUNCT__ 4997 #define __FUNCT__ "MatScale" 4998 /*@ 4999 MatScale - Scales all elements of a matrix by a given number. 5000 5001 Logically Collective on Mat 5002 5003 Input Parameters: 5004 + mat - the matrix to be scaled 5005 - a - the scaling value 5006 5007 Output Parameter: 5008 . mat - the scaled matrix 5009 5010 Level: intermediate 5011 5012 Concepts: matrices^scaling all entries 5013 5014 .seealso: MatDiagonalScale() 5015 @*/ 5016 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5017 { 5018 PetscErrorCode ierr; 5019 5020 PetscFunctionBegin; 5021 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5022 PetscValidType(mat,1); 5023 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5024 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5025 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5026 PetscValidLogicalCollectiveScalar(mat,a,2); 5027 MatCheckPreallocated(mat,1); 5028 5029 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5030 if (a != (PetscScalar)1.0) { 5031 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5032 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5033 } 5034 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5035 #if defined(PETSC_HAVE_CUSP) 5036 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5037 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5038 } 5039 #elif defined(PETSC_HAVE_VIENNACL) 5040 if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) { 5041 mat->valid_GPU_matrix = PETSC_VIENNACL_CPU; 5042 } 5043 #elif defined(PETSC_HAVE_VECCUDA) 5044 if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) { 5045 mat->valid_GPU_matrix = PETSC_CUDA_CPU; 5046 } 5047 #endif 5048 PetscFunctionReturn(0); 5049 } 5050 5051 #undef __FUNCT__ 5052 #define __FUNCT__ "MatNorm" 5053 /*@ 5054 MatNorm - Calculates various norms of a matrix. 5055 5056 Collective on Mat 5057 5058 Input Parameters: 5059 + mat - the matrix 5060 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5061 5062 Output Parameters: 5063 . nrm - the resulting norm 5064 5065 Level: intermediate 5066 5067 Concepts: matrices^norm 5068 Concepts: norm^of matrix 5069 @*/ 5070 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5071 { 5072 PetscErrorCode ierr; 5073 5074 PetscFunctionBegin; 5075 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5076 PetscValidType(mat,1); 5077 PetscValidScalarPointer(nrm,3); 5078 5079 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5080 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5081 if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5082 MatCheckPreallocated(mat,1); 5083 5084 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5085 PetscFunctionReturn(0); 5086 } 5087 5088 /* 5089 This variable is used to prevent counting of MatAssemblyBegin() that 5090 are called from within a MatAssemblyEnd(). 5091 */ 5092 static PetscInt MatAssemblyEnd_InUse = 0; 5093 #undef __FUNCT__ 5094 #define __FUNCT__ "MatAssemblyBegin" 5095 /*@ 5096 MatAssemblyBegin - Begins assembling the matrix. This routine should 5097 be called after completing all calls to MatSetValues(). 5098 5099 Collective on Mat 5100 5101 Input Parameters: 5102 + mat - the matrix 5103 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5104 5105 Notes: 5106 MatSetValues() generally caches the values. The matrix is ready to 5107 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5108 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5109 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5110 using the matrix. 5111 5112 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5113 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 5114 a global collective operation requring all processes that share the matrix. 5115 5116 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5117 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5118 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5119 5120 Level: beginner 5121 5122 Concepts: matrices^assembling 5123 5124 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5125 @*/ 5126 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5127 { 5128 PetscErrorCode ierr; 5129 5130 PetscFunctionBegin; 5131 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5132 PetscValidType(mat,1); 5133 MatCheckPreallocated(mat,1); 5134 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5135 if (mat->assembled) { 5136 mat->was_assembled = PETSC_TRUE; 5137 mat->assembled = PETSC_FALSE; 5138 } 5139 if (!MatAssemblyEnd_InUse) { 5140 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5141 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5142 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5143 } else if (mat->ops->assemblybegin) { 5144 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5145 } 5146 PetscFunctionReturn(0); 5147 } 5148 5149 #undef __FUNCT__ 5150 #define __FUNCT__ "MatAssembled" 5151 /*@ 5152 MatAssembled - Indicates if a matrix has been assembled and is ready for 5153 use; for example, in matrix-vector product. 5154 5155 Not Collective 5156 5157 Input Parameter: 5158 . mat - the matrix 5159 5160 Output Parameter: 5161 . assembled - PETSC_TRUE or PETSC_FALSE 5162 5163 Level: advanced 5164 5165 Concepts: matrices^assembled? 5166 5167 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5168 @*/ 5169 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5170 { 5171 PetscFunctionBegin; 5172 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5173 PetscValidType(mat,1); 5174 PetscValidPointer(assembled,2); 5175 *assembled = mat->assembled; 5176 PetscFunctionReturn(0); 5177 } 5178 5179 #undef __FUNCT__ 5180 #define __FUNCT__ "MatAssemblyEnd" 5181 /*@ 5182 MatAssemblyEnd - Completes assembling the matrix. This routine should 5183 be called after MatAssemblyBegin(). 5184 5185 Collective on Mat 5186 5187 Input Parameters: 5188 + mat - the matrix 5189 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5190 5191 Options Database Keys: 5192 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5193 . -mat_view ::ascii_info_detail - Prints more detailed info 5194 . -mat_view - Prints matrix in ASCII format 5195 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5196 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5197 . -display <name> - Sets display name (default is host) 5198 . -draw_pause <sec> - Sets number of seconds to pause after display 5199 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab ) 5200 . -viewer_socket_machine <machine> - Machine to use for socket 5201 . -viewer_socket_port <port> - Port number to use for socket 5202 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5203 5204 Notes: 5205 MatSetValues() generally caches the values. The matrix is ready to 5206 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5207 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5208 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5209 using the matrix. 5210 5211 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5212 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5213 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5214 5215 Level: beginner 5216 5217 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5218 @*/ 5219 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5220 { 5221 PetscErrorCode ierr; 5222 static PetscInt inassm = 0; 5223 PetscBool flg = PETSC_FALSE; 5224 5225 PetscFunctionBegin; 5226 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5227 PetscValidType(mat,1); 5228 5229 inassm++; 5230 MatAssemblyEnd_InUse++; 5231 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5232 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5233 if (mat->ops->assemblyend) { 5234 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5235 } 5236 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5237 } else if (mat->ops->assemblyend) { 5238 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5239 } 5240 5241 /* Flush assembly is not a true assembly */ 5242 if (type != MAT_FLUSH_ASSEMBLY) { 5243 mat->assembled = PETSC_TRUE; mat->num_ass++; 5244 } 5245 mat->insertmode = NOT_SET_VALUES; 5246 MatAssemblyEnd_InUse--; 5247 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5248 if (!mat->symmetric_eternal) { 5249 mat->symmetric_set = PETSC_FALSE; 5250 mat->hermitian_set = PETSC_FALSE; 5251 mat->structurally_symmetric_set = PETSC_FALSE; 5252 } 5253 #if defined(PETSC_HAVE_CUSP) 5254 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5255 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5256 } 5257 #elif defined(PETSC_HAVE_VIENNACL) 5258 if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) { 5259 mat->valid_GPU_matrix = PETSC_VIENNACL_CPU; 5260 } 5261 #elif defined(PETSC_HAVE_VECCUDA) 5262 if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) { 5263 mat->valid_GPU_matrix = PETSC_CUDA_CPU; 5264 } 5265 #endif 5266 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5267 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5268 5269 if (mat->checksymmetryonassembly) { 5270 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5271 if (flg) { 5272 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5273 } else { 5274 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5275 } 5276 } 5277 if (mat->nullsp && mat->checknullspaceonassembly) { 5278 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5279 } 5280 } 5281 inassm--; 5282 PetscFunctionReturn(0); 5283 } 5284 5285 #undef __FUNCT__ 5286 #define __FUNCT__ "MatSetOption" 5287 /*@ 5288 MatSetOption - Sets a parameter option for a matrix. Some options 5289 may be specific to certain storage formats. Some options 5290 determine how values will be inserted (or added). Sorted, 5291 row-oriented input will generally assemble the fastest. The default 5292 is row-oriented. 5293 5294 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5295 5296 Input Parameters: 5297 + mat - the matrix 5298 . option - the option, one of those listed below (and possibly others), 5299 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5300 5301 Options Describing Matrix Structure: 5302 + MAT_SPD - symmetric positive definite 5303 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5304 . MAT_HERMITIAN - transpose is the complex conjugation 5305 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5306 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5307 you set to be kept with all future use of the matrix 5308 including after MatAssemblyBegin/End() which could 5309 potentially change the symmetry structure, i.e. you 5310 KNOW the matrix will ALWAYS have the property you set. 5311 5312 5313 Options For Use with MatSetValues(): 5314 Insert a logically dense subblock, which can be 5315 . MAT_ROW_ORIENTED - row-oriented (default) 5316 5317 Note these options reflect the data you pass in with MatSetValues(); it has 5318 nothing to do with how the data is stored internally in the matrix 5319 data structure. 5320 5321 When (re)assembling a matrix, we can restrict the input for 5322 efficiency/debugging purposes. These options include: 5323 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5324 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 5325 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5326 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5327 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5328 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5329 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5330 performance for very large process counts. 5331 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5332 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5333 functions, instead sending only neighbor messages. 5334 5335 Notes: 5336 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5337 5338 Some options are relevant only for particular matrix types and 5339 are thus ignored by others. Other options are not supported by 5340 certain matrix types and will generate an error message if set. 5341 5342 If using a Fortran 77 module to compute a matrix, one may need to 5343 use the column-oriented option (or convert to the row-oriented 5344 format). 5345 5346 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5347 that would generate a new entry in the nonzero structure is instead 5348 ignored. Thus, if memory has not alredy been allocated for this particular 5349 data, then the insertion is ignored. For dense matrices, in which 5350 the entire array is allocated, no entries are ever ignored. 5351 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5352 5353 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5354 that would generate a new entry in the nonzero structure instead produces 5355 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 5356 5357 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5358 that would generate a new entry that has not been preallocated will 5359 instead produce an error. (Currently supported for AIJ and BAIJ formats 5360 only.) This is a useful flag when debugging matrix memory preallocation. 5361 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5362 5363 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5364 other processors should be dropped, rather than stashed. 5365 This is useful if you know that the "owning" processor is also 5366 always generating the correct matrix entries, so that PETSc need 5367 not transfer duplicate entries generated on another processor. 5368 5369 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5370 searches during matrix assembly. When this flag is set, the hash table 5371 is created during the first Matrix Assembly. This hash table is 5372 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5373 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5374 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5375 supported by MATMPIBAIJ format only. 5376 5377 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5378 are kept in the nonzero structure 5379 5380 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5381 a zero location in the matrix 5382 5383 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5384 5385 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5386 zero row routines and thus improves performance for very large process counts. 5387 5388 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5389 part of the matrix (since they should match the upper triangular part). 5390 5391 Notes: Can only be called after MatSetSizes() and MatSetType() have been set. 5392 5393 Level: intermediate 5394 5395 Concepts: matrices^setting options 5396 5397 .seealso: MatOption, Mat 5398 5399 @*/ 5400 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5401 { 5402 PetscErrorCode ierr; 5403 5404 PetscFunctionBegin; 5405 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5406 PetscValidType(mat,1); 5407 if (op > 0) { 5408 PetscValidLogicalCollectiveEnum(mat,op,2); 5409 PetscValidLogicalCollectiveBool(mat,flg,3); 5410 } 5411 5412 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); 5413 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()"); 5414 5415 switch (op) { 5416 case MAT_NO_OFF_PROC_ENTRIES: 5417 mat->nooffprocentries = flg; 5418 PetscFunctionReturn(0); 5419 break; 5420 case MAT_SUBSET_OFF_PROC_ENTRIES: 5421 mat->subsetoffprocentries = flg; 5422 PetscFunctionReturn(0); 5423 case MAT_NO_OFF_PROC_ZERO_ROWS: 5424 mat->nooffproczerorows = flg; 5425 PetscFunctionReturn(0); 5426 break; 5427 case MAT_SPD: 5428 mat->spd_set = PETSC_TRUE; 5429 mat->spd = flg; 5430 if (flg) { 5431 mat->symmetric = PETSC_TRUE; 5432 mat->structurally_symmetric = PETSC_TRUE; 5433 mat->symmetric_set = PETSC_TRUE; 5434 mat->structurally_symmetric_set = PETSC_TRUE; 5435 } 5436 break; 5437 case MAT_SYMMETRIC: 5438 mat->symmetric = flg; 5439 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5440 mat->symmetric_set = PETSC_TRUE; 5441 mat->structurally_symmetric_set = flg; 5442 break; 5443 case MAT_HERMITIAN: 5444 mat->hermitian = flg; 5445 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5446 mat->hermitian_set = PETSC_TRUE; 5447 mat->structurally_symmetric_set = flg; 5448 break; 5449 case MAT_STRUCTURALLY_SYMMETRIC: 5450 mat->structurally_symmetric = flg; 5451 mat->structurally_symmetric_set = PETSC_TRUE; 5452 break; 5453 case MAT_SYMMETRY_ETERNAL: 5454 mat->symmetric_eternal = flg; 5455 break; 5456 default: 5457 break; 5458 } 5459 if (mat->ops->setoption) { 5460 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5461 } 5462 PetscFunctionReturn(0); 5463 } 5464 5465 #undef __FUNCT__ 5466 #define __FUNCT__ "MatGetOption" 5467 /*@ 5468 MatGetOption - Gets a parameter option that has been set for a matrix. 5469 5470 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5471 5472 Input Parameters: 5473 + mat - the matrix 5474 - option - the option, this only responds to certain options, check the code for which ones 5475 5476 Output Parameter: 5477 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5478 5479 Notes: Can only be called after MatSetSizes() and MatSetType() have been set. 5480 5481 Level: intermediate 5482 5483 Concepts: matrices^setting options 5484 5485 .seealso: MatOption, MatSetOption() 5486 5487 @*/ 5488 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5489 { 5490 PetscFunctionBegin; 5491 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5492 PetscValidType(mat,1); 5493 5494 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); 5495 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()"); 5496 5497 switch (op) { 5498 case MAT_NO_OFF_PROC_ENTRIES: 5499 *flg = mat->nooffprocentries; 5500 break; 5501 case MAT_NO_OFF_PROC_ZERO_ROWS: 5502 *flg = mat->nooffproczerorows; 5503 break; 5504 case MAT_SYMMETRIC: 5505 *flg = mat->symmetric; 5506 break; 5507 case MAT_HERMITIAN: 5508 *flg = mat->hermitian; 5509 break; 5510 case MAT_STRUCTURALLY_SYMMETRIC: 5511 *flg = mat->structurally_symmetric; 5512 break; 5513 case MAT_SYMMETRY_ETERNAL: 5514 *flg = mat->symmetric_eternal; 5515 break; 5516 default: 5517 break; 5518 } 5519 PetscFunctionReturn(0); 5520 } 5521 5522 #undef __FUNCT__ 5523 #define __FUNCT__ "MatZeroEntries" 5524 /*@ 5525 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5526 this routine retains the old nonzero structure. 5527 5528 Logically Collective on Mat 5529 5530 Input Parameters: 5531 . mat - the matrix 5532 5533 Level: intermediate 5534 5535 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. 5536 See the Performance chapter of the users manual for information on preallocating matrices. 5537 5538 Concepts: matrices^zeroing 5539 5540 .seealso: MatZeroRows() 5541 @*/ 5542 PetscErrorCode MatZeroEntries(Mat mat) 5543 { 5544 PetscErrorCode ierr; 5545 5546 PetscFunctionBegin; 5547 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5548 PetscValidType(mat,1); 5549 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5550 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"); 5551 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5552 MatCheckPreallocated(mat,1); 5553 5554 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5555 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5556 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5557 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5558 #if defined(PETSC_HAVE_CUSP) 5559 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5560 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5561 } 5562 #elif defined(PETSC_HAVE_VIENNACL) 5563 if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) { 5564 mat->valid_GPU_matrix = PETSC_VIENNACL_CPU; 5565 } 5566 #elif defined(PETSC_HAVE_VECCUDA) 5567 if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) { 5568 mat->valid_GPU_matrix = PETSC_CUDA_CPU; 5569 } 5570 #endif 5571 PetscFunctionReturn(0); 5572 } 5573 5574 #undef __FUNCT__ 5575 #define __FUNCT__ "MatZeroRowsColumns" 5576 /*@C 5577 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5578 of a set of rows and columns of a matrix. 5579 5580 Collective on Mat 5581 5582 Input Parameters: 5583 + mat - the matrix 5584 . numRows - the number of rows to remove 5585 . rows - the global row indices 5586 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5587 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5588 - b - optional vector of right hand side, that will be adjusted by provided solution 5589 5590 Notes: 5591 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5592 5593 The user can set a value in the diagonal entry (or for the AIJ and 5594 row formats can optionally remove the main diagonal entry from the 5595 nonzero structure as well, by passing 0.0 as the final argument). 5596 5597 For the parallel case, all processes that share the matrix (i.e., 5598 those in the communicator used for matrix creation) MUST call this 5599 routine, regardless of whether any rows being zeroed are owned by 5600 them. 5601 5602 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5603 list only rows local to itself). 5604 5605 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5606 5607 Level: intermediate 5608 5609 Concepts: matrices^zeroing rows 5610 5611 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS() 5612 @*/ 5613 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5614 { 5615 PetscErrorCode ierr; 5616 5617 PetscFunctionBegin; 5618 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5619 PetscValidType(mat,1); 5620 if (numRows) PetscValidIntPointer(rows,3); 5621 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5622 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5623 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5624 MatCheckPreallocated(mat,1); 5625 5626 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5627 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5628 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5629 #if defined(PETSC_HAVE_CUSP) 5630 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5631 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5632 } 5633 #elif defined(PETSC_HAVE_VIENNACL) 5634 if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) { 5635 mat->valid_GPU_matrix = PETSC_VIENNACL_CPU; 5636 } 5637 #elif defined(PETSC_HAVE_VECCUDA) 5638 if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) { 5639 mat->valid_GPU_matrix = PETSC_CUDA_CPU; 5640 } 5641 #endif 5642 PetscFunctionReturn(0); 5643 } 5644 5645 #undef __FUNCT__ 5646 #define __FUNCT__ "MatZeroRowsColumnsIS" 5647 /*@C 5648 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5649 of a set of rows and columns of a matrix. 5650 5651 Collective on Mat 5652 5653 Input Parameters: 5654 + mat - the matrix 5655 . is - the rows to zero 5656 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5657 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5658 - b - optional vector of right hand side, that will be adjusted by provided solution 5659 5660 Notes: 5661 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5662 5663 The user can set a value in the diagonal entry (or for the AIJ and 5664 row formats can optionally remove the main diagonal entry from the 5665 nonzero structure as well, by passing 0.0 as the final argument). 5666 5667 For the parallel case, all processes that share the matrix (i.e., 5668 those in the communicator used for matrix creation) MUST call this 5669 routine, regardless of whether any rows being zeroed are owned by 5670 them. 5671 5672 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5673 list only rows local to itself). 5674 5675 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5676 5677 Level: intermediate 5678 5679 Concepts: matrices^zeroing rows 5680 5681 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns() 5682 @*/ 5683 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5684 { 5685 PetscErrorCode ierr; 5686 PetscInt numRows; 5687 const PetscInt *rows; 5688 5689 PetscFunctionBegin; 5690 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5691 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5692 PetscValidType(mat,1); 5693 PetscValidType(is,2); 5694 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5695 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5696 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5697 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5698 PetscFunctionReturn(0); 5699 } 5700 5701 #undef __FUNCT__ 5702 #define __FUNCT__ "MatZeroRows" 5703 /*@C 5704 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5705 of a set of rows of a matrix. 5706 5707 Collective on Mat 5708 5709 Input Parameters: 5710 + mat - the matrix 5711 . numRows - the number of rows to remove 5712 . rows - the global row indices 5713 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5714 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5715 - b - optional vector of right hand side, that will be adjusted by provided solution 5716 5717 Notes: 5718 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5719 but does not release memory. For the dense and block diagonal 5720 formats this does not alter the nonzero structure. 5721 5722 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5723 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5724 merely zeroed. 5725 5726 The user can set a value in the diagonal entry (or for the AIJ and 5727 row formats can optionally remove the main diagonal entry from the 5728 nonzero structure as well, by passing 0.0 as the final argument). 5729 5730 For the parallel case, all processes that share the matrix (i.e., 5731 those in the communicator used for matrix creation) MUST call this 5732 routine, regardless of whether any rows being zeroed are owned by 5733 them. 5734 5735 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5736 list only rows local to itself). 5737 5738 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5739 owns that are to be zeroed. This saves a global synchronization in the implementation. 5740 5741 Level: intermediate 5742 5743 Concepts: matrices^zeroing rows 5744 5745 .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5746 @*/ 5747 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5748 { 5749 PetscErrorCode ierr; 5750 5751 PetscFunctionBegin; 5752 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5753 PetscValidType(mat,1); 5754 if (numRows) PetscValidIntPointer(rows,3); 5755 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5756 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5757 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5758 MatCheckPreallocated(mat,1); 5759 5760 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5761 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5762 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5763 #if defined(PETSC_HAVE_CUSP) 5764 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 5765 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 5766 } 5767 #elif defined(PETSC_HAVE_VIENNACL) 5768 if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) { 5769 mat->valid_GPU_matrix = PETSC_VIENNACL_CPU; 5770 } 5771 #elif defined(PETSC_HAVE_VECCUDA) 5772 if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) { 5773 mat->valid_GPU_matrix = PETSC_CUDA_CPU; 5774 } 5775 #endif 5776 PetscFunctionReturn(0); 5777 } 5778 5779 #undef __FUNCT__ 5780 #define __FUNCT__ "MatZeroRowsIS" 5781 /*@C 5782 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5783 of a set of rows of a matrix. 5784 5785 Collective on Mat 5786 5787 Input Parameters: 5788 + mat - the matrix 5789 . is - index set of rows to remove 5790 . diag - value put in all diagonals of eliminated rows 5791 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5792 - b - optional vector of right hand side, that will be adjusted by provided solution 5793 5794 Notes: 5795 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5796 but does not release memory. For the dense and block diagonal 5797 formats this does not alter the nonzero structure. 5798 5799 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5800 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5801 merely zeroed. 5802 5803 The user can set a value in the diagonal entry (or for the AIJ and 5804 row formats can optionally remove the main diagonal entry from the 5805 nonzero structure as well, by passing 0.0 as the final argument). 5806 5807 For the parallel case, all processes that share the matrix (i.e., 5808 those in the communicator used for matrix creation) MUST call this 5809 routine, regardless of whether any rows being zeroed are owned by 5810 them. 5811 5812 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5813 list only rows local to itself). 5814 5815 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5816 owns that are to be zeroed. This saves a global synchronization in the implementation. 5817 5818 Level: intermediate 5819 5820 Concepts: matrices^zeroing rows 5821 5822 .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5823 @*/ 5824 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5825 { 5826 PetscInt numRows; 5827 const PetscInt *rows; 5828 PetscErrorCode ierr; 5829 5830 PetscFunctionBegin; 5831 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5832 PetscValidType(mat,1); 5833 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5834 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5835 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5836 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5837 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5838 PetscFunctionReturn(0); 5839 } 5840 5841 #undef __FUNCT__ 5842 #define __FUNCT__ "MatZeroRowsStencil" 5843 /*@C 5844 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 5845 of a set of rows of a matrix. These rows must be local to the process. 5846 5847 Collective on Mat 5848 5849 Input Parameters: 5850 + mat - the matrix 5851 . numRows - the number of rows to remove 5852 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5853 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5854 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5855 - b - optional vector of right hand side, that will be adjusted by provided solution 5856 5857 Notes: 5858 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5859 but does not release memory. For the dense and block diagonal 5860 formats this does not alter the nonzero structure. 5861 5862 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5863 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5864 merely zeroed. 5865 5866 The user can set a value in the diagonal entry (or for the AIJ and 5867 row formats can optionally remove the main diagonal entry from the 5868 nonzero structure as well, by passing 0.0 as the final argument). 5869 5870 For the parallel case, all processes that share the matrix (i.e., 5871 those in the communicator used for matrix creation) MUST call this 5872 routine, regardless of whether any rows being zeroed are owned by 5873 them. 5874 5875 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5876 list only rows local to itself). 5877 5878 The grid coordinates are across the entire grid, not just the local portion 5879 5880 In Fortran idxm and idxn should be declared as 5881 $ MatStencil idxm(4,m) 5882 and the values inserted using 5883 $ idxm(MatStencil_i,1) = i 5884 $ idxm(MatStencil_j,1) = j 5885 $ idxm(MatStencil_k,1) = k 5886 $ idxm(MatStencil_c,1) = c 5887 etc 5888 5889 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5890 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5891 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5892 DM_BOUNDARY_PERIODIC boundary type. 5893 5894 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 5895 a single value per point) you can skip filling those indices. 5896 5897 Level: intermediate 5898 5899 Concepts: matrices^zeroing rows 5900 5901 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 5902 @*/ 5903 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5904 { 5905 PetscInt dim = mat->stencil.dim; 5906 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5907 PetscInt *dims = mat->stencil.dims+1; 5908 PetscInt *starts = mat->stencil.starts; 5909 PetscInt *dxm = (PetscInt*) rows; 5910 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5911 PetscErrorCode ierr; 5912 5913 PetscFunctionBegin; 5914 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5915 PetscValidType(mat,1); 5916 if (numRows) PetscValidIntPointer(rows,3); 5917 5918 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 5919 for (i = 0; i < numRows; ++i) { 5920 /* Skip unused dimensions (they are ordered k, j, i, c) */ 5921 for (j = 0; j < 3-sdim; ++j) dxm++; 5922 /* Local index in X dir */ 5923 tmp = *dxm++ - starts[0]; 5924 /* Loop over remaining dimensions */ 5925 for (j = 0; j < dim-1; ++j) { 5926 /* If nonlocal, set index to be negative */ 5927 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 5928 /* Update local index */ 5929 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 5930 } 5931 /* Skip component slot if necessary */ 5932 if (mat->stencil.noc) dxm++; 5933 /* Local row number */ 5934 if (tmp >= 0) { 5935 jdxm[numNewRows++] = tmp; 5936 } 5937 } 5938 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 5939 ierr = PetscFree(jdxm);CHKERRQ(ierr); 5940 PetscFunctionReturn(0); 5941 } 5942 5943 #undef __FUNCT__ 5944 #define __FUNCT__ "MatZeroRowsColumnsStencil" 5945 /*@C 5946 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 5947 of a set of rows and columns of a matrix. 5948 5949 Collective on Mat 5950 5951 Input Parameters: 5952 + mat - the matrix 5953 . numRows - the number of rows/columns to remove 5954 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5955 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5956 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5957 - b - optional vector of right hand side, that will be adjusted by provided solution 5958 5959 Notes: 5960 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5961 but does not release memory. For the dense and block diagonal 5962 formats this does not alter the nonzero structure. 5963 5964 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5965 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5966 merely zeroed. 5967 5968 The user can set a value in the diagonal entry (or for the AIJ and 5969 row formats can optionally remove the main diagonal entry from the 5970 nonzero structure as well, by passing 0.0 as the final argument). 5971 5972 For the parallel case, all processes that share the matrix (i.e., 5973 those in the communicator used for matrix creation) MUST call this 5974 routine, regardless of whether any rows being zeroed are owned by 5975 them. 5976 5977 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5978 list only rows local to itself, but the row/column numbers are given in local numbering). 5979 5980 The grid coordinates are across the entire grid, not just the local portion 5981 5982 In Fortran idxm and idxn should be declared as 5983 $ MatStencil idxm(4,m) 5984 and the values inserted using 5985 $ idxm(MatStencil_i,1) = i 5986 $ idxm(MatStencil_j,1) = j 5987 $ idxm(MatStencil_k,1) = k 5988 $ idxm(MatStencil_c,1) = c 5989 etc 5990 5991 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5992 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5993 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5994 DM_BOUNDARY_PERIODIC boundary type. 5995 5996 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 5997 a single value per point) you can skip filling those indices. 5998 5999 Level: intermediate 6000 6001 Concepts: matrices^zeroing rows 6002 6003 .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption() 6004 @*/ 6005 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6006 { 6007 PetscInt dim = mat->stencil.dim; 6008 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6009 PetscInt *dims = mat->stencil.dims+1; 6010 PetscInt *starts = mat->stencil.starts; 6011 PetscInt *dxm = (PetscInt*) rows; 6012 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6013 PetscErrorCode ierr; 6014 6015 PetscFunctionBegin; 6016 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6017 PetscValidType(mat,1); 6018 if (numRows) PetscValidIntPointer(rows,3); 6019 6020 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6021 for (i = 0; i < numRows; ++i) { 6022 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6023 for (j = 0; j < 3-sdim; ++j) dxm++; 6024 /* Local index in X dir */ 6025 tmp = *dxm++ - starts[0]; 6026 /* Loop over remaining dimensions */ 6027 for (j = 0; j < dim-1; ++j) { 6028 /* If nonlocal, set index to be negative */ 6029 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6030 /* Update local index */ 6031 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6032 } 6033 /* Skip component slot if necessary */ 6034 if (mat->stencil.noc) dxm++; 6035 /* Local row number */ 6036 if (tmp >= 0) { 6037 jdxm[numNewRows++] = tmp; 6038 } 6039 } 6040 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6041 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6042 PetscFunctionReturn(0); 6043 } 6044 6045 #undef __FUNCT__ 6046 #define __FUNCT__ "MatZeroRowsLocal" 6047 /*@C 6048 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6049 of a set of rows of a matrix; using local numbering of rows. 6050 6051 Collective on Mat 6052 6053 Input Parameters: 6054 + mat - the matrix 6055 . numRows - the number of rows to remove 6056 . rows - the global row indices 6057 . diag - value put in all diagonals of eliminated rows 6058 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6059 - b - optional vector of right hand side, that will be adjusted by provided solution 6060 6061 Notes: 6062 Before calling MatZeroRowsLocal(), the user must first set the 6063 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6064 6065 For the AIJ matrix formats this removes the old nonzero structure, 6066 but does not release memory. For the dense and block diagonal 6067 formats this does not alter the nonzero structure. 6068 6069 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6070 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6071 merely zeroed. 6072 6073 The user can set a value in the diagonal entry (or for the AIJ and 6074 row formats can optionally remove the main diagonal entry from the 6075 nonzero structure as well, by passing 0.0 as the final argument). 6076 6077 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6078 owns that are to be zeroed. This saves a global synchronization in the implementation. 6079 6080 Level: intermediate 6081 6082 Concepts: matrices^zeroing 6083 6084 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 6085 @*/ 6086 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6087 { 6088 PetscErrorCode ierr; 6089 6090 PetscFunctionBegin; 6091 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6092 PetscValidType(mat,1); 6093 if (numRows) PetscValidIntPointer(rows,3); 6094 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6095 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6096 MatCheckPreallocated(mat,1); 6097 6098 if (mat->ops->zerorowslocal) { 6099 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6100 } else { 6101 IS is, newis; 6102 const PetscInt *newRows; 6103 6104 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6105 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6106 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 6107 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6108 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6109 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6110 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6111 ierr = ISDestroy(&is);CHKERRQ(ierr); 6112 } 6113 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6114 #if defined(PETSC_HAVE_CUSP) 6115 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 6116 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 6117 } 6118 #elif defined(PETSC_HAVE_VIENNACL) 6119 if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) { 6120 mat->valid_GPU_matrix = PETSC_VIENNACL_CPU; 6121 } 6122 #elif defined(PETSC_HAVE_VECCUDA) 6123 if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) { 6124 mat->valid_GPU_matrix = PETSC_CUDA_CPU; 6125 } 6126 #endif 6127 PetscFunctionReturn(0); 6128 } 6129 6130 #undef __FUNCT__ 6131 #define __FUNCT__ "MatZeroRowsLocalIS" 6132 /*@C 6133 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6134 of a set of rows of a matrix; using local numbering of rows. 6135 6136 Collective on Mat 6137 6138 Input Parameters: 6139 + mat - the matrix 6140 . is - index set of rows to remove 6141 . diag - value put in all diagonals of eliminated rows 6142 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6143 - b - optional vector of right hand side, that will be adjusted by provided solution 6144 6145 Notes: 6146 Before calling MatZeroRowsLocalIS(), the user must first set the 6147 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6148 6149 For the AIJ matrix formats this removes the old nonzero structure, 6150 but does not release memory. For the dense and block diagonal 6151 formats this does not alter the nonzero structure. 6152 6153 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6154 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6155 merely zeroed. 6156 6157 The user can set a value in the diagonal entry (or for the AIJ and 6158 row formats can optionally remove the main diagonal entry from the 6159 nonzero structure as well, by passing 0.0 as the final argument). 6160 6161 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6162 owns that are to be zeroed. This saves a global synchronization in the implementation. 6163 6164 Level: intermediate 6165 6166 Concepts: matrices^zeroing 6167 6168 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 6169 @*/ 6170 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6171 { 6172 PetscErrorCode ierr; 6173 PetscInt numRows; 6174 const PetscInt *rows; 6175 6176 PetscFunctionBegin; 6177 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6178 PetscValidType(mat,1); 6179 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6180 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6181 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6182 MatCheckPreallocated(mat,1); 6183 6184 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6185 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6186 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6187 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6188 PetscFunctionReturn(0); 6189 } 6190 6191 #undef __FUNCT__ 6192 #define __FUNCT__ "MatZeroRowsColumnsLocal" 6193 /*@C 6194 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6195 of a set of rows and columns of a matrix; using local numbering of rows. 6196 6197 Collective on Mat 6198 6199 Input Parameters: 6200 + mat - the matrix 6201 . numRows - the number of rows to remove 6202 . rows - the global row indices 6203 . diag - value put in all diagonals of eliminated rows 6204 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6205 - b - optional vector of right hand side, that will be adjusted by provided solution 6206 6207 Notes: 6208 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6209 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6210 6211 The user can set a value in the diagonal entry (or for the AIJ and 6212 row formats can optionally remove the main diagonal entry from the 6213 nonzero structure as well, by passing 0.0 as the final argument). 6214 6215 Level: intermediate 6216 6217 Concepts: matrices^zeroing 6218 6219 .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 6220 @*/ 6221 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6222 { 6223 PetscErrorCode ierr; 6224 IS is, newis; 6225 const PetscInt *newRows; 6226 6227 PetscFunctionBegin; 6228 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6229 PetscValidType(mat,1); 6230 if (numRows) PetscValidIntPointer(rows,3); 6231 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6232 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6233 MatCheckPreallocated(mat,1); 6234 6235 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6236 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6237 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6238 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6239 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6240 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6241 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6242 ierr = ISDestroy(&is);CHKERRQ(ierr); 6243 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6244 #if defined(PETSC_HAVE_CUSP) 6245 if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) { 6246 mat->valid_GPU_matrix = PETSC_CUSP_CPU; 6247 } 6248 #elif defined(PETSC_HAVE_VIENNACL) 6249 if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) { 6250 mat->valid_GPU_matrix = PETSC_VIENNACL_CPU; 6251 } 6252 #elif defined(PETSC_HAVE_VECCUDA) 6253 if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) { 6254 mat->valid_GPU_matrix = PETSC_CUDA_CPU; 6255 } 6256 #endif 6257 PetscFunctionReturn(0); 6258 } 6259 6260 #undef __FUNCT__ 6261 #define __FUNCT__ "MatZeroRowsColumnsLocalIS" 6262 /*@C 6263 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6264 of a set of rows and columns of a matrix; using local numbering of rows. 6265 6266 Collective on Mat 6267 6268 Input Parameters: 6269 + mat - the matrix 6270 . is - index set of rows to remove 6271 . diag - value put in all diagonals of eliminated rows 6272 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6273 - b - optional vector of right hand side, that will be adjusted by provided solution 6274 6275 Notes: 6276 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6277 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6278 6279 The user can set a value in the diagonal entry (or for the AIJ and 6280 row formats can optionally remove the main diagonal entry from the 6281 nonzero structure as well, by passing 0.0 as the final argument). 6282 6283 Level: intermediate 6284 6285 Concepts: matrices^zeroing 6286 6287 .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping 6288 @*/ 6289 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6290 { 6291 PetscErrorCode ierr; 6292 PetscInt numRows; 6293 const PetscInt *rows; 6294 6295 PetscFunctionBegin; 6296 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6297 PetscValidType(mat,1); 6298 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6299 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6300 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6301 MatCheckPreallocated(mat,1); 6302 6303 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6304 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6305 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6306 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6307 PetscFunctionReturn(0); 6308 } 6309 6310 #undef __FUNCT__ 6311 #define __FUNCT__ "MatGetSize" 6312 /*@ 6313 MatGetSize - Returns the numbers of rows and columns in a matrix. 6314 6315 Not Collective 6316 6317 Input Parameter: 6318 . mat - the matrix 6319 6320 Output Parameters: 6321 + m - the number of global rows 6322 - n - the number of global columns 6323 6324 Note: both output parameters can be NULL on input. 6325 6326 Level: beginner 6327 6328 Concepts: matrices^size 6329 6330 .seealso: MatGetLocalSize() 6331 @*/ 6332 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6333 { 6334 PetscFunctionBegin; 6335 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6336 if (m) *m = mat->rmap->N; 6337 if (n) *n = mat->cmap->N; 6338 PetscFunctionReturn(0); 6339 } 6340 6341 #undef __FUNCT__ 6342 #define __FUNCT__ "MatGetLocalSize" 6343 /*@ 6344 MatGetLocalSize - Returns the number of rows and columns in a matrix 6345 stored locally. This information may be implementation dependent, so 6346 use with care. 6347 6348 Not Collective 6349 6350 Input Parameters: 6351 . mat - the matrix 6352 6353 Output Parameters: 6354 + m - the number of local rows 6355 - n - the number of local columns 6356 6357 Note: both output parameters can be NULL on input. 6358 6359 Level: beginner 6360 6361 Concepts: matrices^local size 6362 6363 .seealso: MatGetSize() 6364 @*/ 6365 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6366 { 6367 PetscFunctionBegin; 6368 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6369 if (m) PetscValidIntPointer(m,2); 6370 if (n) PetscValidIntPointer(n,3); 6371 if (m) *m = mat->rmap->n; 6372 if (n) *n = mat->cmap->n; 6373 PetscFunctionReturn(0); 6374 } 6375 6376 #undef __FUNCT__ 6377 #define __FUNCT__ "MatGetOwnershipRangeColumn" 6378 /*@ 6379 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6380 this processor. (The columns of the "diagonal block") 6381 6382 Not Collective, unless matrix has not been allocated, then collective on Mat 6383 6384 Input Parameters: 6385 . mat - the matrix 6386 6387 Output Parameters: 6388 + m - the global index of the first local column 6389 - n - one more than the global index of the last local column 6390 6391 Notes: both output parameters can be NULL on input. 6392 6393 Level: developer 6394 6395 Concepts: matrices^column ownership 6396 6397 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6398 6399 @*/ 6400 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6401 { 6402 PetscFunctionBegin; 6403 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6404 PetscValidType(mat,1); 6405 if (m) PetscValidIntPointer(m,2); 6406 if (n) PetscValidIntPointer(n,3); 6407 MatCheckPreallocated(mat,1); 6408 if (m) *m = mat->cmap->rstart; 6409 if (n) *n = mat->cmap->rend; 6410 PetscFunctionReturn(0); 6411 } 6412 6413 #undef __FUNCT__ 6414 #define __FUNCT__ "MatGetOwnershipRange" 6415 /*@ 6416 MatGetOwnershipRange - Returns the range of matrix rows owned by 6417 this processor, assuming that the matrix is laid out with the first 6418 n1 rows on the first processor, the next n2 rows on the second, etc. 6419 For certain parallel layouts this range may not be well defined. 6420 6421 Not Collective 6422 6423 Input Parameters: 6424 . mat - the matrix 6425 6426 Output Parameters: 6427 + m - the global index of the first local row 6428 - n - one more than the global index of the last local row 6429 6430 Note: Both output parameters can be NULL on input. 6431 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6432 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6433 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6434 6435 Level: beginner 6436 6437 Concepts: matrices^row ownership 6438 6439 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6440 6441 @*/ 6442 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6443 { 6444 PetscFunctionBegin; 6445 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6446 PetscValidType(mat,1); 6447 if (m) PetscValidIntPointer(m,2); 6448 if (n) PetscValidIntPointer(n,3); 6449 MatCheckPreallocated(mat,1); 6450 if (m) *m = mat->rmap->rstart; 6451 if (n) *n = mat->rmap->rend; 6452 PetscFunctionReturn(0); 6453 } 6454 6455 #undef __FUNCT__ 6456 #define __FUNCT__ "MatGetOwnershipRanges" 6457 /*@C 6458 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6459 each process 6460 6461 Not Collective, unless matrix has not been allocated, then collective on Mat 6462 6463 Input Parameters: 6464 . mat - the matrix 6465 6466 Output Parameters: 6467 . ranges - start of each processors portion plus one more than the total length at the end 6468 6469 Level: beginner 6470 6471 Concepts: matrices^row ownership 6472 6473 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6474 6475 @*/ 6476 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6477 { 6478 PetscErrorCode ierr; 6479 6480 PetscFunctionBegin; 6481 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6482 PetscValidType(mat,1); 6483 MatCheckPreallocated(mat,1); 6484 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6485 PetscFunctionReturn(0); 6486 } 6487 6488 #undef __FUNCT__ 6489 #define __FUNCT__ "MatGetOwnershipRangesColumn" 6490 /*@C 6491 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6492 this processor. (The columns of the "diagonal blocks" for each process) 6493 6494 Not Collective, unless matrix has not been allocated, then collective on Mat 6495 6496 Input Parameters: 6497 . mat - the matrix 6498 6499 Output Parameters: 6500 . ranges - start of each processors portion plus one more then the total length at the end 6501 6502 Level: beginner 6503 6504 Concepts: matrices^column ownership 6505 6506 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6507 6508 @*/ 6509 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6510 { 6511 PetscErrorCode ierr; 6512 6513 PetscFunctionBegin; 6514 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6515 PetscValidType(mat,1); 6516 MatCheckPreallocated(mat,1); 6517 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6518 PetscFunctionReturn(0); 6519 } 6520 6521 #undef __FUNCT__ 6522 #define __FUNCT__ "MatGetOwnershipIS" 6523 /*@C 6524 MatGetOwnershipIS - Get row and column ownership as index sets 6525 6526 Not Collective 6527 6528 Input Arguments: 6529 . A - matrix of type Elemental 6530 6531 Output Arguments: 6532 + rows - rows in which this process owns elements 6533 . cols - columns in which this process owns elements 6534 6535 Level: intermediate 6536 6537 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues() 6538 @*/ 6539 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6540 { 6541 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6542 6543 PetscFunctionBegin; 6544 MatCheckPreallocated(A,1); 6545 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6546 if (f) { 6547 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6548 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6549 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6550 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6551 } 6552 PetscFunctionReturn(0); 6553 } 6554 6555 #undef __FUNCT__ 6556 #define __FUNCT__ "MatILUFactorSymbolic" 6557 /*@C 6558 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6559 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6560 to complete the factorization. 6561 6562 Collective on Mat 6563 6564 Input Parameters: 6565 + mat - the matrix 6566 . row - row permutation 6567 . column - column permutation 6568 - info - structure containing 6569 $ levels - number of levels of fill. 6570 $ expected fill - as ratio of original fill. 6571 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6572 missing diagonal entries) 6573 6574 Output Parameters: 6575 . fact - new matrix that has been symbolically factored 6576 6577 Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6578 6579 Most users should employ the simplified KSP interface for linear solvers 6580 instead of working directly with matrix algebra routines such as this. 6581 See, e.g., KSPCreate(). 6582 6583 Level: developer 6584 6585 Concepts: matrices^symbolic LU factorization 6586 Concepts: matrices^factorization 6587 Concepts: LU^symbolic factorization 6588 6589 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6590 MatGetOrdering(), MatFactorInfo 6591 6592 Developer Note: fortran interface is not autogenerated as the f90 6593 interface defintion cannot be generated correctly [due to MatFactorInfo] 6594 6595 @*/ 6596 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6597 { 6598 PetscErrorCode ierr; 6599 6600 PetscFunctionBegin; 6601 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6602 PetscValidType(mat,1); 6603 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6604 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6605 PetscValidPointer(info,4); 6606 PetscValidPointer(fact,5); 6607 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6608 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6609 if (!(fact)->ops->ilufactorsymbolic) { 6610 const MatSolverPackage spackage; 6611 ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr); 6612 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6613 } 6614 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6615 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6616 MatCheckPreallocated(mat,2); 6617 6618 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6619 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6620 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6621 PetscFunctionReturn(0); 6622 } 6623 6624 #undef __FUNCT__ 6625 #define __FUNCT__ "MatICCFactorSymbolic" 6626 /*@C 6627 MatICCFactorSymbolic - Performs symbolic incomplete 6628 Cholesky factorization for a symmetric matrix. Use 6629 MatCholeskyFactorNumeric() to complete the factorization. 6630 6631 Collective on Mat 6632 6633 Input Parameters: 6634 + mat - the matrix 6635 . perm - row and column permutation 6636 - info - structure containing 6637 $ levels - number of levels of fill. 6638 $ expected fill - as ratio of original fill. 6639 6640 Output Parameter: 6641 . fact - the factored matrix 6642 6643 Notes: 6644 Most users should employ the KSP interface for linear solvers 6645 instead of working directly with matrix algebra routines such as this. 6646 See, e.g., KSPCreate(). 6647 6648 Level: developer 6649 6650 Concepts: matrices^symbolic incomplete Cholesky factorization 6651 Concepts: matrices^factorization 6652 Concepts: Cholsky^symbolic factorization 6653 6654 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6655 6656 Developer Note: fortran interface is not autogenerated as the f90 6657 interface defintion cannot be generated correctly [due to MatFactorInfo] 6658 6659 @*/ 6660 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6661 { 6662 PetscErrorCode ierr; 6663 6664 PetscFunctionBegin; 6665 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6666 PetscValidType(mat,1); 6667 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6668 PetscValidPointer(info,3); 6669 PetscValidPointer(fact,4); 6670 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6671 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6672 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6673 if (!(fact)->ops->iccfactorsymbolic) { 6674 const MatSolverPackage spackage; 6675 ierr = MatFactorGetSolverPackage(fact,&spackage);CHKERRQ(ierr); 6676 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6677 } 6678 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6679 MatCheckPreallocated(mat,2); 6680 6681 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6682 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6683 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6684 PetscFunctionReturn(0); 6685 } 6686 6687 #undef __FUNCT__ 6688 #define __FUNCT__ "MatGetSubMatrices" 6689 /*@C 6690 MatGetSubMatrices - Extracts several submatrices from a matrix. If submat 6691 points to an array of valid matrices, they may be reused to store the new 6692 submatrices. 6693 6694 Collective on Mat 6695 6696 Input Parameters: 6697 + mat - the matrix 6698 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6699 . irow, icol - index sets of rows and columns to extract 6700 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6701 6702 Output Parameter: 6703 . submat - the array of submatrices 6704 6705 Notes: 6706 MatGetSubMatrices() can extract ONLY sequential submatrices 6707 (from both sequential and parallel matrices). Use MatGetSubMatrix() 6708 to extract a parallel submatrix. 6709 6710 Some matrix types place restrictions on the row and column 6711 indices, such as that they be sorted or that they be equal to each other. 6712 6713 The index sets may not have duplicate entries. 6714 6715 When extracting submatrices from a parallel matrix, each processor can 6716 form a different submatrix by setting the rows and columns of its 6717 individual index sets according to the local submatrix desired. 6718 6719 When finished using the submatrices, the user should destroy 6720 them with MatDestroyMatrices(). 6721 6722 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6723 original matrix has not changed from that last call to MatGetSubMatrices(). 6724 6725 This routine creates the matrices in submat; you should NOT create them before 6726 calling it. It also allocates the array of matrix pointers submat. 6727 6728 For BAIJ matrices the index sets must respect the block structure, that is if they 6729 request one row/column in a block, they must request all rows/columns that are in 6730 that block. For example, if the block size is 2 you cannot request just row 0 and 6731 column 0. 6732 6733 Fortran Note: 6734 The Fortran interface is slightly different from that given below; it 6735 requires one to pass in as submat a Mat (integer) array of size at least m. 6736 6737 Level: advanced 6738 6739 Concepts: matrices^accessing submatrices 6740 Concepts: submatrices 6741 6742 .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6743 @*/ 6744 PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6745 { 6746 PetscErrorCode ierr; 6747 PetscInt i; 6748 PetscBool eq; 6749 6750 PetscFunctionBegin; 6751 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6752 PetscValidType(mat,1); 6753 if (n) { 6754 PetscValidPointer(irow,3); 6755 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6756 PetscValidPointer(icol,4); 6757 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6758 } 6759 PetscValidPointer(submat,6); 6760 if (n && scall == MAT_REUSE_MATRIX) { 6761 PetscValidPointer(*submat,6); 6762 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6763 } 6764 if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6765 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6766 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6767 MatCheckPreallocated(mat,1); 6768 6769 ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6770 ierr = (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6771 ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6772 for (i=0; i<n; i++) { 6773 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6774 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6775 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6776 if (eq) { 6777 if (mat->symmetric) { 6778 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6779 } else if (mat->hermitian) { 6780 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6781 } else if (mat->structurally_symmetric) { 6782 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6783 } 6784 } 6785 } 6786 } 6787 PetscFunctionReturn(0); 6788 } 6789 6790 #undef __FUNCT__ 6791 #define __FUNCT__ "MatGetSubMatricesMPI" 6792 PetscErrorCode MatGetSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6793 { 6794 PetscErrorCode ierr; 6795 PetscInt i; 6796 PetscBool eq; 6797 6798 PetscFunctionBegin; 6799 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6800 PetscValidType(mat,1); 6801 if (n) { 6802 PetscValidPointer(irow,3); 6803 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6804 PetscValidPointer(icol,4); 6805 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6806 } 6807 PetscValidPointer(submat,6); 6808 if (n && scall == MAT_REUSE_MATRIX) { 6809 PetscValidPointer(*submat,6); 6810 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6811 } 6812 if (!mat->ops->getsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6813 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6814 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6815 MatCheckPreallocated(mat,1); 6816 6817 ierr = PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6818 ierr = (*mat->ops->getsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6819 ierr = PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);CHKERRQ(ierr); 6820 for (i=0; i<n; i++) { 6821 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6822 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6823 if (eq) { 6824 if (mat->symmetric) { 6825 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6826 } else if (mat->hermitian) { 6827 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6828 } else if (mat->structurally_symmetric) { 6829 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6830 } 6831 } 6832 } 6833 } 6834 PetscFunctionReturn(0); 6835 } 6836 6837 #undef __FUNCT__ 6838 #define __FUNCT__ "MatDestroyMatrices" 6839 /*@C 6840 MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices(). 6841 6842 Collective on Mat 6843 6844 Input Parameters: 6845 + n - the number of local matrices 6846 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6847 sequence of MatGetSubMatrices()) 6848 6849 Level: advanced 6850 6851 Notes: Frees not only the matrices, but also the array that contains the matrices 6852 In Fortran will not free the array. 6853 6854 .seealso: MatGetSubMatrices() 6855 @*/ 6856 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6857 { 6858 PetscErrorCode ierr; 6859 PetscInt i; 6860 6861 PetscFunctionBegin; 6862 if (!*mat) PetscFunctionReturn(0); 6863 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6864 PetscValidPointer(mat,2); 6865 for (i=0; i<n; i++) { 6866 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 6867 } 6868 /* memory is allocated even if n = 0 */ 6869 ierr = PetscFree(*mat);CHKERRQ(ierr); 6870 *mat = NULL; 6871 PetscFunctionReturn(0); 6872 } 6873 6874 #undef __FUNCT__ 6875 #define __FUNCT__ "MatGetSeqNonzeroStructure" 6876 /*@C 6877 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 6878 6879 Collective on Mat 6880 6881 Input Parameters: 6882 . mat - the matrix 6883 6884 Output Parameter: 6885 . matstruct - the sequential matrix with the nonzero structure of mat 6886 6887 Level: intermediate 6888 6889 .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices() 6890 @*/ 6891 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 6892 { 6893 PetscErrorCode ierr; 6894 6895 PetscFunctionBegin; 6896 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6897 PetscValidPointer(matstruct,2); 6898 6899 PetscValidType(mat,1); 6900 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6901 MatCheckPreallocated(mat,1); 6902 6903 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 6904 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6905 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 6906 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6907 PetscFunctionReturn(0); 6908 } 6909 6910 #undef __FUNCT__ 6911 #define __FUNCT__ "MatDestroySeqNonzeroStructure" 6912 /*@C 6913 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 6914 6915 Collective on Mat 6916 6917 Input Parameters: 6918 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 6919 sequence of MatGetSequentialNonzeroStructure()) 6920 6921 Level: advanced 6922 6923 Notes: Frees not only the matrices, but also the array that contains the matrices 6924 6925 .seealso: MatGetSeqNonzeroStructure() 6926 @*/ 6927 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 6928 { 6929 PetscErrorCode ierr; 6930 6931 PetscFunctionBegin; 6932 PetscValidPointer(mat,1); 6933 ierr = MatDestroy(mat);CHKERRQ(ierr); 6934 PetscFunctionReturn(0); 6935 } 6936 6937 #undef __FUNCT__ 6938 #define __FUNCT__ "MatIncreaseOverlap" 6939 /*@ 6940 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 6941 replaces the index sets by larger ones that represent submatrices with 6942 additional overlap. 6943 6944 Collective on Mat 6945 6946 Input Parameters: 6947 + mat - the matrix 6948 . n - the number of index sets 6949 . is - the array of index sets (these index sets will changed during the call) 6950 - ov - the additional overlap requested 6951 6952 Options Database: 6953 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 6954 6955 Level: developer 6956 6957 Concepts: overlap 6958 Concepts: ASM^computing overlap 6959 6960 .seealso: MatGetSubMatrices() 6961 @*/ 6962 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 6963 { 6964 PetscErrorCode ierr; 6965 6966 PetscFunctionBegin; 6967 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6968 PetscValidType(mat,1); 6969 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 6970 if (n) { 6971 PetscValidPointer(is,3); 6972 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 6973 } 6974 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6975 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6976 MatCheckPreallocated(mat,1); 6977 6978 if (!ov) PetscFunctionReturn(0); 6979 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6980 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6981 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 6982 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 6983 PetscFunctionReturn(0); 6984 } 6985 6986 6987 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 6988 6989 #undef __FUNCT__ 6990 #define __FUNCT__ "MatIncreaseOverlapSplit" 6991 /*@ 6992 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 6993 a sub communicator, replaces the index sets by larger ones that represent submatrices with 6994 additional overlap. 6995 6996 Collective on Mat 6997 6998 Input Parameters: 6999 + mat - the matrix 7000 . n - the number of index sets 7001 . is - the array of index sets (these index sets will changed during the call) 7002 - ov - the additional overlap requested 7003 7004 Options Database: 7005 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7006 7007 Level: developer 7008 7009 Concepts: overlap 7010 Concepts: ASM^computing overlap 7011 7012 .seealso: MatGetSubMatrices() 7013 @*/ 7014 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7015 { 7016 PetscInt i; 7017 PetscErrorCode ierr; 7018 7019 PetscFunctionBegin; 7020 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7021 PetscValidType(mat,1); 7022 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7023 if (n) { 7024 PetscValidPointer(is,3); 7025 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7026 } 7027 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7028 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7029 MatCheckPreallocated(mat,1); 7030 if (!ov) PetscFunctionReturn(0); 7031 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7032 for(i=0; i<n; i++){ 7033 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 7034 } 7035 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7036 PetscFunctionReturn(0); 7037 } 7038 7039 7040 7041 7042 #undef __FUNCT__ 7043 #define __FUNCT__ "MatGetBlockSize" 7044 /*@ 7045 MatGetBlockSize - Returns the matrix block size. 7046 7047 Not Collective 7048 7049 Input Parameter: 7050 . mat - the matrix 7051 7052 Output Parameter: 7053 . bs - block size 7054 7055 Notes: 7056 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7057 7058 If the block size has not been set yet this routine returns 1. 7059 7060 Level: intermediate 7061 7062 Concepts: matrices^block size 7063 7064 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7065 @*/ 7066 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7067 { 7068 PetscFunctionBegin; 7069 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7070 PetscValidIntPointer(bs,2); 7071 *bs = PetscAbs(mat->rmap->bs); 7072 PetscFunctionReturn(0); 7073 } 7074 7075 #undef __FUNCT__ 7076 #define __FUNCT__ "MatGetBlockSizes" 7077 /*@ 7078 MatGetBlockSizes - Returns the matrix block row and column sizes. 7079 7080 Not Collective 7081 7082 Input Parameter: 7083 . mat - the matrix 7084 7085 Output Parameter: 7086 . rbs - row block size 7087 . cbs - coumn block size 7088 7089 Notes: 7090 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7091 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7092 7093 If a block size has not been set yet this routine returns 1. 7094 7095 Level: intermediate 7096 7097 Concepts: matrices^block size 7098 7099 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7100 @*/ 7101 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7102 { 7103 PetscFunctionBegin; 7104 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7105 if (rbs) PetscValidIntPointer(rbs,2); 7106 if (cbs) PetscValidIntPointer(cbs,3); 7107 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7108 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7109 PetscFunctionReturn(0); 7110 } 7111 7112 #undef __FUNCT__ 7113 #define __FUNCT__ "MatSetBlockSize" 7114 /*@ 7115 MatSetBlockSize - Sets the matrix block size. 7116 7117 Logically Collective on Mat 7118 7119 Input Parameters: 7120 + mat - the matrix 7121 - bs - block size 7122 7123 Notes: 7124 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7125 7126 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 7127 7128 Level: intermediate 7129 7130 Concepts: matrices^block size 7131 7132 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7133 @*/ 7134 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7135 { 7136 PetscErrorCode ierr; 7137 7138 PetscFunctionBegin; 7139 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7140 PetscValidLogicalCollectiveInt(mat,bs,2); 7141 ierr = PetscLayoutSetBlockSize(mat->rmap,bs);CHKERRQ(ierr); 7142 ierr = PetscLayoutSetBlockSize(mat->cmap,bs);CHKERRQ(ierr); 7143 PetscFunctionReturn(0); 7144 } 7145 7146 #undef __FUNCT__ 7147 #define __FUNCT__ "MatSetBlockSizes" 7148 /*@ 7149 MatSetBlockSizes - Sets the matrix block row and column sizes. 7150 7151 Logically Collective on Mat 7152 7153 Input Parameters: 7154 + mat - the matrix 7155 - rbs - row block size 7156 - cbs - column block size 7157 7158 Notes: 7159 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7160 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7161 7162 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 7163 7164 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7165 7166 Level: intermediate 7167 7168 Concepts: matrices^block size 7169 7170 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7171 @*/ 7172 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7173 { 7174 PetscErrorCode ierr; 7175 7176 PetscFunctionBegin; 7177 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7178 PetscValidLogicalCollectiveInt(mat,rbs,2); 7179 PetscValidLogicalCollectiveInt(mat,cbs,3); 7180 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7181 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7182 PetscFunctionReturn(0); 7183 } 7184 7185 #undef __FUNCT__ 7186 #define __FUNCT__ "MatSetBlockSizesFromMats" 7187 /*@ 7188 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7189 7190 Logically Collective on Mat 7191 7192 Input Parameters: 7193 + mat - the matrix 7194 . fromRow - matrix from which to copy row block size 7195 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7196 7197 Level: developer 7198 7199 Concepts: matrices^block size 7200 7201 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7202 @*/ 7203 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7204 { 7205 PetscErrorCode ierr; 7206 7207 PetscFunctionBegin; 7208 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7209 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7210 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7211 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7212 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7213 PetscFunctionReturn(0); 7214 } 7215 7216 #undef __FUNCT__ 7217 #define __FUNCT__ "MatResidual" 7218 /*@ 7219 MatResidual - Default routine to calculate the residual. 7220 7221 Collective on Mat and Vec 7222 7223 Input Parameters: 7224 + mat - the matrix 7225 . b - the right-hand-side 7226 - x - the approximate solution 7227 7228 Output Parameter: 7229 . r - location to store the residual 7230 7231 Level: developer 7232 7233 .keywords: MG, default, multigrid, residual 7234 7235 .seealso: PCMGSetResidual() 7236 @*/ 7237 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7238 { 7239 PetscErrorCode ierr; 7240 7241 PetscFunctionBegin; 7242 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7243 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7244 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7245 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7246 PetscValidType(mat,1); 7247 MatCheckPreallocated(mat,1); 7248 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7249 if (!mat->ops->residual) { 7250 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7251 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7252 } else { 7253 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7254 } 7255 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7256 PetscFunctionReturn(0); 7257 } 7258 7259 #undef __FUNCT__ 7260 #define __FUNCT__ "MatGetRowIJ" 7261 /*@C 7262 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7263 7264 Collective on Mat 7265 7266 Input Parameters: 7267 + mat - the matrix 7268 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7269 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7270 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7271 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7272 always used. 7273 7274 Output Parameters: 7275 + n - number of rows in the (possibly compressed) matrix 7276 . ia - the row pointers [of length n+1] 7277 . ja - the column indices 7278 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7279 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7280 7281 Level: developer 7282 7283 Notes: You CANNOT change any of the ia[] or ja[] values. 7284 7285 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values 7286 7287 Fortran Node 7288 7289 In Fortran use 7290 $ PetscInt ia(1), ja(1) 7291 $ PetscOffset iia, jja 7292 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7293 $ Acess the ith and jth entries via ia(iia + i) and ja(jja + j) 7294 $ 7295 $ or 7296 $ 7297 $ PetscInt, pointer :: ia(:),ja(:) 7298 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7299 $ Acess the ith and jth entries via ia(i) and ja(j) 7300 7301 7302 7303 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7304 @*/ 7305 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7306 { 7307 PetscErrorCode ierr; 7308 7309 PetscFunctionBegin; 7310 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7311 PetscValidType(mat,1); 7312 PetscValidIntPointer(n,4); 7313 if (ia) PetscValidIntPointer(ia,5); 7314 if (ja) PetscValidIntPointer(ja,6); 7315 PetscValidIntPointer(done,7); 7316 MatCheckPreallocated(mat,1); 7317 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7318 else { 7319 *done = PETSC_TRUE; 7320 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7321 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7322 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7323 } 7324 PetscFunctionReturn(0); 7325 } 7326 7327 #undef __FUNCT__ 7328 #define __FUNCT__ "MatGetColumnIJ" 7329 /*@C 7330 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7331 7332 Collective on Mat 7333 7334 Input Parameters: 7335 + mat - the matrix 7336 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7337 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7338 symmetrized 7339 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7340 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7341 always used. 7342 . n - number of columns in the (possibly compressed) matrix 7343 . ia - the column pointers 7344 - ja - the row indices 7345 7346 Output Parameters: 7347 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7348 7349 Note: 7350 This routine zeros out n, ia, and ja. This is to prevent accidental 7351 us of the array after it has been restored. If you pass NULL, it will 7352 not zero the pointers. Use of ia or ja after MatRestoreColumnIJ() is invalid. 7353 7354 Level: developer 7355 7356 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7357 @*/ 7358 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7359 { 7360 PetscErrorCode ierr; 7361 7362 PetscFunctionBegin; 7363 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7364 PetscValidType(mat,1); 7365 PetscValidIntPointer(n,4); 7366 if (ia) PetscValidIntPointer(ia,5); 7367 if (ja) PetscValidIntPointer(ja,6); 7368 PetscValidIntPointer(done,7); 7369 MatCheckPreallocated(mat,1); 7370 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7371 else { 7372 *done = PETSC_TRUE; 7373 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7374 } 7375 PetscFunctionReturn(0); 7376 } 7377 7378 #undef __FUNCT__ 7379 #define __FUNCT__ "MatRestoreRowIJ" 7380 /*@C 7381 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7382 MatGetRowIJ(). 7383 7384 Collective on Mat 7385 7386 Input Parameters: 7387 + mat - the matrix 7388 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7389 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7390 symmetrized 7391 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7392 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7393 always used. 7394 . n - size of (possibly compressed) matrix 7395 . ia - the row pointers 7396 - ja - the column indices 7397 7398 Output Parameters: 7399 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7400 7401 Note: 7402 This routine zeros out n, ia, and ja. This is to prevent accidental 7403 us of the array after it has been restored. If you pass NULL, it will 7404 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7405 7406 Level: developer 7407 7408 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7409 @*/ 7410 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7411 { 7412 PetscErrorCode ierr; 7413 7414 PetscFunctionBegin; 7415 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7416 PetscValidType(mat,1); 7417 if (ia) PetscValidIntPointer(ia,5); 7418 if (ja) PetscValidIntPointer(ja,6); 7419 PetscValidIntPointer(done,7); 7420 MatCheckPreallocated(mat,1); 7421 7422 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7423 else { 7424 *done = PETSC_TRUE; 7425 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7426 if (n) *n = 0; 7427 if (ia) *ia = NULL; 7428 if (ja) *ja = NULL; 7429 } 7430 PetscFunctionReturn(0); 7431 } 7432 7433 #undef __FUNCT__ 7434 #define __FUNCT__ "MatRestoreColumnIJ" 7435 /*@C 7436 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7437 MatGetColumnIJ(). 7438 7439 Collective on Mat 7440 7441 Input Parameters: 7442 + mat - the matrix 7443 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7444 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7445 symmetrized 7446 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7447 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7448 always used. 7449 7450 Output Parameters: 7451 + n - size of (possibly compressed) matrix 7452 . ia - the column pointers 7453 . ja - the row indices 7454 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7455 7456 Level: developer 7457 7458 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7459 @*/ 7460 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7461 { 7462 PetscErrorCode ierr; 7463 7464 PetscFunctionBegin; 7465 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7466 PetscValidType(mat,1); 7467 if (ia) PetscValidIntPointer(ia,5); 7468 if (ja) PetscValidIntPointer(ja,6); 7469 PetscValidIntPointer(done,7); 7470 MatCheckPreallocated(mat,1); 7471 7472 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7473 else { 7474 *done = PETSC_TRUE; 7475 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7476 if (n) *n = 0; 7477 if (ia) *ia = NULL; 7478 if (ja) *ja = NULL; 7479 } 7480 PetscFunctionReturn(0); 7481 } 7482 7483 #undef __FUNCT__ 7484 #define __FUNCT__ "MatColoringPatch" 7485 /*@C 7486 MatColoringPatch -Used inside matrix coloring routines that 7487 use MatGetRowIJ() and/or MatGetColumnIJ(). 7488 7489 Collective on Mat 7490 7491 Input Parameters: 7492 + mat - the matrix 7493 . ncolors - max color value 7494 . n - number of entries in colorarray 7495 - colorarray - array indicating color for each column 7496 7497 Output Parameters: 7498 . iscoloring - coloring generated using colorarray information 7499 7500 Level: developer 7501 7502 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7503 7504 @*/ 7505 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7506 { 7507 PetscErrorCode ierr; 7508 7509 PetscFunctionBegin; 7510 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7511 PetscValidType(mat,1); 7512 PetscValidIntPointer(colorarray,4); 7513 PetscValidPointer(iscoloring,5); 7514 MatCheckPreallocated(mat,1); 7515 7516 if (!mat->ops->coloringpatch) { 7517 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7518 } else { 7519 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7520 } 7521 PetscFunctionReturn(0); 7522 } 7523 7524 7525 #undef __FUNCT__ 7526 #define __FUNCT__ "MatSetUnfactored" 7527 /*@ 7528 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7529 7530 Logically Collective on Mat 7531 7532 Input Parameter: 7533 . mat - the factored matrix to be reset 7534 7535 Notes: 7536 This routine should be used only with factored matrices formed by in-place 7537 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7538 format). This option can save memory, for example, when solving nonlinear 7539 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7540 ILU(0) preconditioner. 7541 7542 Note that one can specify in-place ILU(0) factorization by calling 7543 .vb 7544 PCType(pc,PCILU); 7545 PCFactorSeUseInPlace(pc); 7546 .ve 7547 or by using the options -pc_type ilu -pc_factor_in_place 7548 7549 In-place factorization ILU(0) can also be used as a local 7550 solver for the blocks within the block Jacobi or additive Schwarz 7551 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7552 for details on setting local solver options. 7553 7554 Most users should employ the simplified KSP interface for linear solvers 7555 instead of working directly with matrix algebra routines such as this. 7556 See, e.g., KSPCreate(). 7557 7558 Level: developer 7559 7560 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7561 7562 Concepts: matrices^unfactored 7563 7564 @*/ 7565 PetscErrorCode MatSetUnfactored(Mat mat) 7566 { 7567 PetscErrorCode ierr; 7568 7569 PetscFunctionBegin; 7570 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7571 PetscValidType(mat,1); 7572 MatCheckPreallocated(mat,1); 7573 mat->factortype = MAT_FACTOR_NONE; 7574 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7575 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7576 PetscFunctionReturn(0); 7577 } 7578 7579 /*MC 7580 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7581 7582 Synopsis: 7583 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7584 7585 Not collective 7586 7587 Input Parameter: 7588 . x - matrix 7589 7590 Output Parameters: 7591 + xx_v - the Fortran90 pointer to the array 7592 - ierr - error code 7593 7594 Example of Usage: 7595 .vb 7596 PetscScalar, pointer xx_v(:,:) 7597 .... 7598 call MatDenseGetArrayF90(x,xx_v,ierr) 7599 a = xx_v(3) 7600 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7601 .ve 7602 7603 Level: advanced 7604 7605 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7606 7607 Concepts: matrices^accessing array 7608 7609 M*/ 7610 7611 /*MC 7612 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7613 accessed with MatDenseGetArrayF90(). 7614 7615 Synopsis: 7616 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7617 7618 Not collective 7619 7620 Input Parameters: 7621 + x - matrix 7622 - xx_v - the Fortran90 pointer to the array 7623 7624 Output Parameter: 7625 . ierr - error code 7626 7627 Example of Usage: 7628 .vb 7629 PetscScalar, pointer xx_v(:,:) 7630 .... 7631 call MatDenseGetArrayF90(x,xx_v,ierr) 7632 a = xx_v(3) 7633 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7634 .ve 7635 7636 Level: advanced 7637 7638 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7639 7640 M*/ 7641 7642 7643 /*MC 7644 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7645 7646 Synopsis: 7647 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7648 7649 Not collective 7650 7651 Input Parameter: 7652 . x - matrix 7653 7654 Output Parameters: 7655 + xx_v - the Fortran90 pointer to the array 7656 - ierr - error code 7657 7658 Example of Usage: 7659 .vb 7660 PetscScalar, pointer xx_v(:) 7661 .... 7662 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7663 a = xx_v(3) 7664 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7665 .ve 7666 7667 Level: advanced 7668 7669 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7670 7671 Concepts: matrices^accessing array 7672 7673 M*/ 7674 7675 /*MC 7676 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7677 accessed with MatSeqAIJGetArrayF90(). 7678 7679 Synopsis: 7680 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7681 7682 Not collective 7683 7684 Input Parameters: 7685 + x - matrix 7686 - xx_v - the Fortran90 pointer to the array 7687 7688 Output Parameter: 7689 . ierr - error code 7690 7691 Example of Usage: 7692 .vb 7693 PetscScalar, pointer xx_v(:) 7694 .... 7695 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7696 a = xx_v(3) 7697 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7698 .ve 7699 7700 Level: advanced 7701 7702 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7703 7704 M*/ 7705 7706 7707 #undef __FUNCT__ 7708 #define __FUNCT__ "MatGetSubMatrix" 7709 /*@ 7710 MatGetSubMatrix - Gets a single submatrix on the same number of processors 7711 as the original matrix. 7712 7713 Collective on Mat 7714 7715 Input Parameters: 7716 + mat - the original matrix 7717 . isrow - parallel IS containing the rows this processor should obtain 7718 . 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. 7719 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7720 7721 Output Parameter: 7722 . newmat - the new submatrix, of the same type as the old 7723 7724 Level: advanced 7725 7726 Notes: 7727 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7728 7729 Some matrix types place restrictions on the row and column indices, such 7730 as that they be sorted or that they be equal to each other. 7731 7732 The index sets may not have duplicate entries. 7733 7734 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7735 the MatGetSubMatrix() routine will create the newmat for you. Any additional calls 7736 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7737 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7738 you are finished using it. 7739 7740 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7741 the input matrix. 7742 7743 If iscol is NULL then all columns are obtained (not supported in Fortran). 7744 7745 Example usage: 7746 Consider the following 8x8 matrix with 34 non-zero values, that is 7747 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7748 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7749 as follows: 7750 7751 .vb 7752 1 2 0 | 0 3 0 | 0 4 7753 Proc0 0 5 6 | 7 0 0 | 8 0 7754 9 0 10 | 11 0 0 | 12 0 7755 ------------------------------------- 7756 13 0 14 | 15 16 17 | 0 0 7757 Proc1 0 18 0 | 19 20 21 | 0 0 7758 0 0 0 | 22 23 0 | 24 0 7759 ------------------------------------- 7760 Proc2 25 26 27 | 0 0 28 | 29 0 7761 30 0 0 | 31 32 33 | 0 34 7762 .ve 7763 7764 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7765 7766 .vb 7767 2 0 | 0 3 0 | 0 7768 Proc0 5 6 | 7 0 0 | 8 7769 ------------------------------- 7770 Proc1 18 0 | 19 20 21 | 0 7771 ------------------------------- 7772 Proc2 26 27 | 0 0 28 | 29 7773 0 0 | 31 32 33 | 0 7774 .ve 7775 7776 7777 Concepts: matrices^submatrices 7778 7779 .seealso: MatGetSubMatrices() 7780 @*/ 7781 PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7782 { 7783 PetscErrorCode ierr; 7784 PetscMPIInt size; 7785 Mat *local; 7786 IS iscoltmp; 7787 7788 PetscFunctionBegin; 7789 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7790 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7791 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7792 PetscValidPointer(newmat,5); 7793 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7794 PetscValidType(mat,1); 7795 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7796 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 7797 7798 MatCheckPreallocated(mat,1); 7799 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 7800 7801 if (!iscol || isrow == iscol) { 7802 PetscBool stride; 7803 PetscMPIInt grabentirematrix = 0,grab; 7804 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 7805 if (stride) { 7806 PetscInt first,step,n,rstart,rend; 7807 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 7808 if (step == 1) { 7809 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 7810 if (rstart == first) { 7811 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 7812 if (n == rend-rstart) { 7813 grabentirematrix = 1; 7814 } 7815 } 7816 } 7817 } 7818 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 7819 if (grab) { 7820 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 7821 if (cll == MAT_INITIAL_MATRIX) { 7822 *newmat = mat; 7823 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 7824 } 7825 PetscFunctionReturn(0); 7826 } 7827 } 7828 7829 if (!iscol) { 7830 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 7831 } else { 7832 iscoltmp = iscol; 7833 } 7834 7835 /* if original matrix is on just one processor then use submatrix generated */ 7836 if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 7837 ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 7838 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7839 PetscFunctionReturn(0); 7840 } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) { 7841 ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 7842 *newmat = *local; 7843 ierr = PetscFree(local);CHKERRQ(ierr); 7844 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7845 PetscFunctionReturn(0); 7846 } else if (!mat->ops->getsubmatrix) { 7847 /* Create a new matrix type that implements the operation using the full matrix */ 7848 ierr = PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr); 7849 switch (cll) { 7850 case MAT_INITIAL_MATRIX: 7851 ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 7852 break; 7853 case MAT_REUSE_MATRIX: 7854 ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 7855 break; 7856 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 7857 } 7858 ierr = PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr); 7859 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7860 PetscFunctionReturn(0); 7861 } 7862 7863 if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7864 ierr = PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr); 7865 ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 7866 ierr = PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr); 7867 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7868 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 7869 PetscFunctionReturn(0); 7870 } 7871 7872 #undef __FUNCT__ 7873 #define __FUNCT__ "MatStashSetInitialSize" 7874 /*@ 7875 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 7876 used during the assembly process to store values that belong to 7877 other processors. 7878 7879 Not Collective 7880 7881 Input Parameters: 7882 + mat - the matrix 7883 . size - the initial size of the stash. 7884 - bsize - the initial size of the block-stash(if used). 7885 7886 Options Database Keys: 7887 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 7888 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 7889 7890 Level: intermediate 7891 7892 Notes: 7893 The block-stash is used for values set with MatSetValuesBlocked() while 7894 the stash is used for values set with MatSetValues() 7895 7896 Run with the option -info and look for output of the form 7897 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 7898 to determine the appropriate value, MM, to use for size and 7899 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 7900 to determine the value, BMM to use for bsize 7901 7902 Concepts: stash^setting matrix size 7903 Concepts: matrices^stash 7904 7905 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 7906 7907 @*/ 7908 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 7909 { 7910 PetscErrorCode ierr; 7911 7912 PetscFunctionBegin; 7913 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7914 PetscValidType(mat,1); 7915 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 7916 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 7917 PetscFunctionReturn(0); 7918 } 7919 7920 #undef __FUNCT__ 7921 #define __FUNCT__ "MatInterpolateAdd" 7922 /*@ 7923 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 7924 the matrix 7925 7926 Neighbor-wise Collective on Mat 7927 7928 Input Parameters: 7929 + mat - the matrix 7930 . x,y - the vectors 7931 - w - where the result is stored 7932 7933 Level: intermediate 7934 7935 Notes: 7936 w may be the same vector as y. 7937 7938 This allows one to use either the restriction or interpolation (its transpose) 7939 matrix to do the interpolation 7940 7941 Concepts: interpolation 7942 7943 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 7944 7945 @*/ 7946 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 7947 { 7948 PetscErrorCode ierr; 7949 PetscInt M,N,Ny; 7950 7951 PetscFunctionBegin; 7952 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7953 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7954 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 7955 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 7956 PetscValidType(A,1); 7957 MatCheckPreallocated(A,1); 7958 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 7959 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 7960 if (M == Ny) { 7961 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 7962 } else { 7963 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 7964 } 7965 PetscFunctionReturn(0); 7966 } 7967 7968 #undef __FUNCT__ 7969 #define __FUNCT__ "MatInterpolate" 7970 /*@ 7971 MatInterpolate - y = A*x or A'*x depending on the shape of 7972 the matrix 7973 7974 Neighbor-wise Collective on Mat 7975 7976 Input Parameters: 7977 + mat - the matrix 7978 - x,y - the vectors 7979 7980 Level: intermediate 7981 7982 Notes: 7983 This allows one to use either the restriction or interpolation (its transpose) 7984 matrix to do the interpolation 7985 7986 Concepts: matrices^interpolation 7987 7988 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 7989 7990 @*/ 7991 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 7992 { 7993 PetscErrorCode ierr; 7994 PetscInt M,N,Ny; 7995 7996 PetscFunctionBegin; 7997 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 7998 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 7999 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8000 PetscValidType(A,1); 8001 MatCheckPreallocated(A,1); 8002 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8003 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8004 if (M == Ny) { 8005 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8006 } else { 8007 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8008 } 8009 PetscFunctionReturn(0); 8010 } 8011 8012 #undef __FUNCT__ 8013 #define __FUNCT__ "MatRestrict" 8014 /*@ 8015 MatRestrict - y = A*x or A'*x 8016 8017 Neighbor-wise Collective on Mat 8018 8019 Input Parameters: 8020 + mat - the matrix 8021 - x,y - the vectors 8022 8023 Level: intermediate 8024 8025 Notes: 8026 This allows one to use either the restriction or interpolation (its transpose) 8027 matrix to do the restriction 8028 8029 Concepts: matrices^restriction 8030 8031 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8032 8033 @*/ 8034 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8035 { 8036 PetscErrorCode ierr; 8037 PetscInt M,N,Ny; 8038 8039 PetscFunctionBegin; 8040 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8041 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8042 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8043 PetscValidType(A,1); 8044 MatCheckPreallocated(A,1); 8045 8046 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8047 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8048 if (M == Ny) { 8049 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8050 } else { 8051 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8052 } 8053 PetscFunctionReturn(0); 8054 } 8055 8056 #undef __FUNCT__ 8057 #define __FUNCT__ "MatGetNullSpace" 8058 /*@ 8059 MatGetNullSpace - retrieves the null space to a matrix. 8060 8061 Logically Collective on Mat and MatNullSpace 8062 8063 Input Parameters: 8064 + mat - the matrix 8065 - nullsp - the null space object 8066 8067 Level: developer 8068 8069 Concepts: null space^attaching to matrix 8070 8071 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8072 @*/ 8073 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8074 { 8075 PetscFunctionBegin; 8076 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8077 PetscValidType(mat,1); 8078 PetscValidPointer(nullsp,2); 8079 *nullsp = mat->nullsp; 8080 PetscFunctionReturn(0); 8081 } 8082 8083 #undef __FUNCT__ 8084 #define __FUNCT__ "MatSetNullSpace" 8085 /*@ 8086 MatSetNullSpace - attaches a null space to a matrix. 8087 8088 Logically Collective on Mat and MatNullSpace 8089 8090 Input Parameters: 8091 + mat - the matrix 8092 - nullsp - the null space object 8093 8094 Level: advanced 8095 8096 Notes: 8097 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8098 8099 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8100 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8101 8102 You can remove the null space by calling this routine with an nullsp of NULL 8103 8104 8105 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8106 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). 8107 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 8108 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 8109 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). 8110 8111 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8112 8113 Concepts: null space^attaching to matrix 8114 8115 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8116 @*/ 8117 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8118 { 8119 PetscErrorCode ierr; 8120 8121 PetscFunctionBegin; 8122 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8123 PetscValidType(mat,1); 8124 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8125 MatCheckPreallocated(mat,1); 8126 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8127 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8128 mat->nullsp = nullsp; 8129 PetscFunctionReturn(0); 8130 } 8131 8132 #undef __FUNCT__ 8133 #define __FUNCT__ "MatGetTransposeNullSpace" 8134 /*@ 8135 MatGetTransposeNullSpace - retrieves the null space to a matrix. 8136 8137 Logically Collective on Mat and MatNullSpace 8138 8139 Input Parameters: 8140 + mat - the matrix 8141 - nullsp - the null space object 8142 8143 Level: developer 8144 8145 Notes: 8146 This null space is used by solvers. Overwrites any previous null space that may have been attached 8147 8148 Concepts: null space^attaching to matrix 8149 8150 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace() 8151 @*/ 8152 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8153 { 8154 PetscFunctionBegin; 8155 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8156 PetscValidType(mat,1); 8157 PetscValidPointer(nullsp,2); 8158 *nullsp = mat->transnullsp; 8159 PetscFunctionReturn(0); 8160 } 8161 8162 #undef __FUNCT__ 8163 #define __FUNCT__ "MatSetTransposeNullSpace" 8164 /*@ 8165 MatSetTransposeNullSpace - attaches a null space to a matrix. 8166 8167 Logically Collective on Mat and MatNullSpace 8168 8169 Input Parameters: 8170 + mat - the matrix 8171 - nullsp - the null space object 8172 8173 Level: advanced 8174 8175 Notes: 8176 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. 8177 You must also call MatSetNullSpace() 8178 8179 8180 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8181 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). 8182 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 8183 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 8184 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). 8185 8186 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8187 8188 Concepts: null space^attaching to matrix 8189 8190 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetNullSpace(), MatNullSpaceRemove() 8191 @*/ 8192 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8193 { 8194 PetscErrorCode ierr; 8195 8196 PetscFunctionBegin; 8197 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8198 PetscValidType(mat,1); 8199 PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8200 MatCheckPreallocated(mat,1); 8201 ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr); 8202 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8203 mat->transnullsp = nullsp; 8204 PetscFunctionReturn(0); 8205 } 8206 8207 #undef __FUNCT__ 8208 #define __FUNCT__ "MatSetNearNullSpace" 8209 /*@ 8210 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8211 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8212 8213 Logically Collective on Mat and MatNullSpace 8214 8215 Input Parameters: 8216 + mat - the matrix 8217 - nullsp - the null space object 8218 8219 Level: advanced 8220 8221 Notes: 8222 Overwrites any previous near null space that may have been attached 8223 8224 You can remove the null space by calling this routine with an nullsp of NULL 8225 8226 Concepts: null space^attaching to matrix 8227 8228 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody() 8229 @*/ 8230 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8231 { 8232 PetscErrorCode ierr; 8233 8234 PetscFunctionBegin; 8235 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8236 PetscValidType(mat,1); 8237 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8238 MatCheckPreallocated(mat,1); 8239 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8240 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8241 mat->nearnullsp = nullsp; 8242 PetscFunctionReturn(0); 8243 } 8244 8245 #undef __FUNCT__ 8246 #define __FUNCT__ "MatGetNearNullSpace" 8247 /*@ 8248 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8249 8250 Not Collective 8251 8252 Input Parameters: 8253 . mat - the matrix 8254 8255 Output Parameters: 8256 . nullsp - the null space object, NULL if not set 8257 8258 Level: developer 8259 8260 Concepts: null space^attaching to matrix 8261 8262 .seealso: MatSetNearNullSpace(), MatGetNullSpace() 8263 @*/ 8264 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8265 { 8266 PetscFunctionBegin; 8267 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8268 PetscValidType(mat,1); 8269 PetscValidPointer(nullsp,2); 8270 MatCheckPreallocated(mat,1); 8271 *nullsp = mat->nearnullsp; 8272 PetscFunctionReturn(0); 8273 } 8274 8275 #undef __FUNCT__ 8276 #define __FUNCT__ "MatICCFactor" 8277 /*@C 8278 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8279 8280 Collective on Mat 8281 8282 Input Parameters: 8283 + mat - the matrix 8284 . row - row/column permutation 8285 . fill - expected fill factor >= 1.0 8286 - level - level of fill, for ICC(k) 8287 8288 Notes: 8289 Probably really in-place only when level of fill is zero, otherwise allocates 8290 new space to store factored matrix and deletes previous memory. 8291 8292 Most users should employ the simplified KSP interface for linear solvers 8293 instead of working directly with matrix algebra routines such as this. 8294 See, e.g., KSPCreate(). 8295 8296 Level: developer 8297 8298 Concepts: matrices^incomplete Cholesky factorization 8299 Concepts: Cholesky factorization 8300 8301 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8302 8303 Developer Note: fortran interface is not autogenerated as the f90 8304 interface defintion cannot be generated correctly [due to MatFactorInfo] 8305 8306 @*/ 8307 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8308 { 8309 PetscErrorCode ierr; 8310 8311 PetscFunctionBegin; 8312 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8313 PetscValidType(mat,1); 8314 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8315 PetscValidPointer(info,3); 8316 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8317 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8318 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8319 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8320 MatCheckPreallocated(mat,1); 8321 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8322 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8323 PetscFunctionReturn(0); 8324 } 8325 8326 #undef __FUNCT__ 8327 #define __FUNCT__ "MatSetValuesAdifor" 8328 /*@ 8329 MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix. 8330 8331 Not Collective 8332 8333 Input Parameters: 8334 + mat - the matrix 8335 . nl - leading dimension of v 8336 - v - the values compute with ADIFOR 8337 8338 Level: developer 8339 8340 Notes: 8341 Must call MatSetColoring() before using this routine. Also this matrix must already 8342 have its nonzero pattern determined. 8343 8344 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 8345 MatSetValues(), MatSetColoring() 8346 @*/ 8347 PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v) 8348 { 8349 PetscErrorCode ierr; 8350 8351 PetscFunctionBegin; 8352 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8353 PetscValidType(mat,1); 8354 PetscValidPointer(v,3); 8355 8356 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8357 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 8358 if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8359 ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr); 8360 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 8361 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8362 PetscFunctionReturn(0); 8363 } 8364 8365 #undef __FUNCT__ 8366 #define __FUNCT__ "MatDiagonalScaleLocal" 8367 /*@ 8368 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8369 ghosted ones. 8370 8371 Not Collective 8372 8373 Input Parameters: 8374 + mat - the matrix 8375 - diag = the diagonal values, including ghost ones 8376 8377 Level: developer 8378 8379 Notes: Works only for MPIAIJ and MPIBAIJ matrices 8380 8381 .seealso: MatDiagonalScale() 8382 @*/ 8383 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8384 { 8385 PetscErrorCode ierr; 8386 PetscMPIInt size; 8387 8388 PetscFunctionBegin; 8389 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8390 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8391 PetscValidType(mat,1); 8392 8393 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8394 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8395 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8396 if (size == 1) { 8397 PetscInt n,m; 8398 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8399 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8400 if (m == n) { 8401 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8402 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8403 } else { 8404 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8405 } 8406 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8407 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8408 PetscFunctionReturn(0); 8409 } 8410 8411 #undef __FUNCT__ 8412 #define __FUNCT__ "MatGetInertia" 8413 /*@ 8414 MatGetInertia - Gets the inertia from a factored matrix 8415 8416 Collective on Mat 8417 8418 Input Parameter: 8419 . mat - the matrix 8420 8421 Output Parameters: 8422 + nneg - number of negative eigenvalues 8423 . nzero - number of zero eigenvalues 8424 - npos - number of positive eigenvalues 8425 8426 Level: advanced 8427 8428 Notes: Matrix must have been factored by MatCholeskyFactor() 8429 8430 8431 @*/ 8432 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8433 { 8434 PetscErrorCode ierr; 8435 8436 PetscFunctionBegin; 8437 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8438 PetscValidType(mat,1); 8439 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8440 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8441 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8442 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8443 PetscFunctionReturn(0); 8444 } 8445 8446 /* ----------------------------------------------------------------*/ 8447 #undef __FUNCT__ 8448 #define __FUNCT__ "MatSolves" 8449 /*@C 8450 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8451 8452 Neighbor-wise Collective on Mat and Vecs 8453 8454 Input Parameters: 8455 + mat - the factored matrix 8456 - b - the right-hand-side vectors 8457 8458 Output Parameter: 8459 . x - the result vectors 8460 8461 Notes: 8462 The vectors b and x cannot be the same. I.e., one cannot 8463 call MatSolves(A,x,x). 8464 8465 Notes: 8466 Most users should employ the simplified KSP interface for linear solvers 8467 instead of working directly with matrix algebra routines such as this. 8468 See, e.g., KSPCreate(). 8469 8470 Level: developer 8471 8472 Concepts: matrices^triangular solves 8473 8474 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8475 @*/ 8476 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8477 { 8478 PetscErrorCode ierr; 8479 8480 PetscFunctionBegin; 8481 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8482 PetscValidType(mat,1); 8483 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8484 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8485 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8486 8487 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8488 MatCheckPreallocated(mat,1); 8489 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8490 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8491 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8492 PetscFunctionReturn(0); 8493 } 8494 8495 #undef __FUNCT__ 8496 #define __FUNCT__ "MatIsSymmetric" 8497 /*@ 8498 MatIsSymmetric - Test whether a matrix is symmetric 8499 8500 Collective on Mat 8501 8502 Input Parameter: 8503 + A - the matrix to test 8504 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8505 8506 Output Parameters: 8507 . flg - the result 8508 8509 Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8510 8511 Level: intermediate 8512 8513 Concepts: matrix^symmetry 8514 8515 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8516 @*/ 8517 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8518 { 8519 PetscErrorCode ierr; 8520 8521 PetscFunctionBegin; 8522 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8523 PetscValidPointer(flg,2); 8524 8525 if (!A->symmetric_set) { 8526 if (!A->ops->issymmetric) { 8527 MatType mattype; 8528 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8529 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8530 } 8531 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8532 if (!tol) { 8533 A->symmetric_set = PETSC_TRUE; 8534 A->symmetric = *flg; 8535 if (A->symmetric) { 8536 A->structurally_symmetric_set = PETSC_TRUE; 8537 A->structurally_symmetric = PETSC_TRUE; 8538 } 8539 } 8540 } else if (A->symmetric) { 8541 *flg = PETSC_TRUE; 8542 } else if (!tol) { 8543 *flg = PETSC_FALSE; 8544 } else { 8545 if (!A->ops->issymmetric) { 8546 MatType mattype; 8547 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8548 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8549 } 8550 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8551 } 8552 PetscFunctionReturn(0); 8553 } 8554 8555 #undef __FUNCT__ 8556 #define __FUNCT__ "MatIsHermitian" 8557 /*@ 8558 MatIsHermitian - Test whether a matrix is Hermitian 8559 8560 Collective on Mat 8561 8562 Input Parameter: 8563 + A - the matrix to test 8564 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8565 8566 Output Parameters: 8567 . flg - the result 8568 8569 Level: intermediate 8570 8571 Concepts: matrix^symmetry 8572 8573 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8574 MatIsSymmetricKnown(), MatIsSymmetric() 8575 @*/ 8576 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8577 { 8578 PetscErrorCode ierr; 8579 8580 PetscFunctionBegin; 8581 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8582 PetscValidPointer(flg,2); 8583 8584 if (!A->hermitian_set) { 8585 if (!A->ops->ishermitian) { 8586 MatType mattype; 8587 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8588 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8589 } 8590 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8591 if (!tol) { 8592 A->hermitian_set = PETSC_TRUE; 8593 A->hermitian = *flg; 8594 if (A->hermitian) { 8595 A->structurally_symmetric_set = PETSC_TRUE; 8596 A->structurally_symmetric = PETSC_TRUE; 8597 } 8598 } 8599 } else if (A->hermitian) { 8600 *flg = PETSC_TRUE; 8601 } else if (!tol) { 8602 *flg = PETSC_FALSE; 8603 } else { 8604 if (!A->ops->ishermitian) { 8605 MatType mattype; 8606 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8607 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8608 } 8609 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8610 } 8611 PetscFunctionReturn(0); 8612 } 8613 8614 #undef __FUNCT__ 8615 #define __FUNCT__ "MatIsSymmetricKnown" 8616 /*@ 8617 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8618 8619 Not Collective 8620 8621 Input Parameter: 8622 . A - the matrix to check 8623 8624 Output Parameters: 8625 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8626 - flg - the result 8627 8628 Level: advanced 8629 8630 Concepts: matrix^symmetry 8631 8632 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8633 if you want it explicitly checked 8634 8635 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8636 @*/ 8637 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8638 { 8639 PetscFunctionBegin; 8640 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8641 PetscValidPointer(set,2); 8642 PetscValidPointer(flg,3); 8643 if (A->symmetric_set) { 8644 *set = PETSC_TRUE; 8645 *flg = A->symmetric; 8646 } else { 8647 *set = PETSC_FALSE; 8648 } 8649 PetscFunctionReturn(0); 8650 } 8651 8652 #undef __FUNCT__ 8653 #define __FUNCT__ "MatIsHermitianKnown" 8654 /*@ 8655 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8656 8657 Not Collective 8658 8659 Input Parameter: 8660 . A - the matrix to check 8661 8662 Output Parameters: 8663 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8664 - flg - the result 8665 8666 Level: advanced 8667 8668 Concepts: matrix^symmetry 8669 8670 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8671 if you want it explicitly checked 8672 8673 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8674 @*/ 8675 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8676 { 8677 PetscFunctionBegin; 8678 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8679 PetscValidPointer(set,2); 8680 PetscValidPointer(flg,3); 8681 if (A->hermitian_set) { 8682 *set = PETSC_TRUE; 8683 *flg = A->hermitian; 8684 } else { 8685 *set = PETSC_FALSE; 8686 } 8687 PetscFunctionReturn(0); 8688 } 8689 8690 #undef __FUNCT__ 8691 #define __FUNCT__ "MatIsStructurallySymmetric" 8692 /*@ 8693 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8694 8695 Collective on Mat 8696 8697 Input Parameter: 8698 . A - the matrix to test 8699 8700 Output Parameters: 8701 . flg - the result 8702 8703 Level: intermediate 8704 8705 Concepts: matrix^symmetry 8706 8707 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8708 @*/ 8709 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8710 { 8711 PetscErrorCode ierr; 8712 8713 PetscFunctionBegin; 8714 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8715 PetscValidPointer(flg,2); 8716 if (!A->structurally_symmetric_set) { 8717 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8718 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8719 8720 A->structurally_symmetric_set = PETSC_TRUE; 8721 } 8722 *flg = A->structurally_symmetric; 8723 PetscFunctionReturn(0); 8724 } 8725 8726 #undef __FUNCT__ 8727 #define __FUNCT__ "MatStashGetInfo" 8728 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*); 8729 /*@ 8730 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8731 to be communicated to other processors during the MatAssemblyBegin/End() process 8732 8733 Not collective 8734 8735 Input Parameter: 8736 . vec - the vector 8737 8738 Output Parameters: 8739 + nstash - the size of the stash 8740 . reallocs - the number of additional mallocs incurred. 8741 . bnstash - the size of the block stash 8742 - breallocs - the number of additional mallocs incurred.in the block stash 8743 8744 Level: advanced 8745 8746 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8747 8748 @*/ 8749 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8750 { 8751 PetscErrorCode ierr; 8752 8753 PetscFunctionBegin; 8754 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8755 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8756 PetscFunctionReturn(0); 8757 } 8758 8759 #undef __FUNCT__ 8760 #define __FUNCT__ "MatCreateVecs" 8761 /*@C 8762 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8763 parallel layout 8764 8765 Collective on Mat 8766 8767 Input Parameter: 8768 . mat - the matrix 8769 8770 Output Parameter: 8771 + right - (optional) vector that the matrix can be multiplied against 8772 - left - (optional) vector that the matrix vector product can be stored in 8773 8774 Notes: 8775 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(). 8776 8777 Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8778 8779 Level: advanced 8780 8781 .seealso: MatCreate(), VecDestroy() 8782 @*/ 8783 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8784 { 8785 PetscErrorCode ierr; 8786 8787 PetscFunctionBegin; 8788 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8789 PetscValidType(mat,1); 8790 if (mat->ops->getvecs) { 8791 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8792 } else { 8793 PetscInt rbs,cbs; 8794 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8795 if (right) { 8796 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8797 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8798 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8799 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8800 ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr); 8801 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8802 } 8803 if (left) { 8804 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8805 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8806 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8807 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8808 ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr); 8809 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8810 } 8811 } 8812 PetscFunctionReturn(0); 8813 } 8814 8815 #undef __FUNCT__ 8816 #define __FUNCT__ "MatFactorInfoInitialize" 8817 /*@C 8818 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8819 with default values. 8820 8821 Not Collective 8822 8823 Input Parameters: 8824 . info - the MatFactorInfo data structure 8825 8826 8827 Notes: The solvers are generally used through the KSP and PC objects, for example 8828 PCLU, PCILU, PCCHOLESKY, PCICC 8829 8830 Level: developer 8831 8832 .seealso: MatFactorInfo 8833 8834 Developer Note: fortran interface is not autogenerated as the f90 8835 interface defintion cannot be generated correctly [due to MatFactorInfo] 8836 8837 @*/ 8838 8839 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8840 { 8841 PetscErrorCode ierr; 8842 8843 PetscFunctionBegin; 8844 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8845 PetscFunctionReturn(0); 8846 } 8847 8848 #undef __FUNCT__ 8849 #define __FUNCT__ "MatFactorSetSchurIS" 8850 /*@ 8851 MatFactorSetSchurIS - Set indices corresponding to the Schur complement 8852 8853 Collective on Mat 8854 8855 Input Parameters: 8856 + mat - the factored matrix 8857 - is - the index set defining the Schur indices (0-based) 8858 8859 Notes: 8860 8861 Level: developer 8862 8863 Concepts: 8864 8865 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement() 8866 8867 @*/ 8868 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 8869 { 8870 PetscErrorCode ierr,(*f)(Mat,IS); 8871 8872 PetscFunctionBegin; 8873 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8874 PetscValidType(mat,1); 8875 PetscValidHeaderSpecific(is,IS_CLASSID,2); 8876 PetscValidType(is,2); 8877 PetscCheckSameComm(mat,1,is,2); 8878 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 8879 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 8880 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"); 8881 ierr = (*f)(mat,is);CHKERRQ(ierr); 8882 PetscFunctionReturn(0); 8883 } 8884 8885 #undef __FUNCT__ 8886 #define __FUNCT__ "MatFactorCreateSchurComplement" 8887 /*@ 8888 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 8889 8890 Logically Collective on Mat 8891 8892 Input Parameters: 8893 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 8894 . *S - location where to return the Schur complement (MATDENSE) 8895 8896 Notes: 8897 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. 8898 If MatFactorInvertSchurComplement has been called, the routine gets back the inverse 8899 8900 Level: advanced 8901 8902 References: 8903 8904 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement() 8905 @*/ 8906 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S) 8907 { 8908 PetscErrorCode ierr; 8909 8910 PetscFunctionBegin; 8911 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8912 ierr = PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*),(F,S));CHKERRQ(ierr); 8913 PetscFunctionReturn(0); 8914 } 8915 8916 #undef __FUNCT__ 8917 #define __FUNCT__ "MatFactorGetSchurComplement" 8918 /*@ 8919 MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data 8920 8921 Logically Collective on Mat 8922 8923 Input Parameters: 8924 + F - the factored matrix obtained by calling MatGetFactor() 8925 . *S - location where to return the Schur complement (in MATDENSE format) 8926 8927 Notes: 8928 Schur complement mode is currently implemented for sequential matrices. 8929 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. 8930 The caller should call MatFactorRestoreSchurComplement when the object is no longer needed. 8931 8932 Level: advanced 8933 8934 References: 8935 8936 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement() 8937 @*/ 8938 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S) 8939 { 8940 PetscErrorCode ierr; 8941 8942 PetscFunctionBegin; 8943 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8944 ierr = PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*),(F,S));CHKERRQ(ierr); 8945 PetscFunctionReturn(0); 8946 } 8947 8948 #undef __FUNCT__ 8949 #define __FUNCT__ "MatFactorRestoreSchurComplement" 8950 /*@ 8951 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 8952 8953 Logically Collective on Mat 8954 8955 Input Parameters: 8956 + F - the factored matrix obtained by calling MatGetFactor() 8957 . *S - location where the Schur complement is stored 8958 8959 Notes: 8960 8961 Level: advanced 8962 8963 References: 8964 8965 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement() 8966 @*/ 8967 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S) 8968 { 8969 PetscErrorCode ierr; 8970 8971 PetscFunctionBegin; 8972 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8973 PetscValidHeaderSpecific(*S,MAT_CLASSID,1); 8974 ierr = MatDestroy(S);CHKERRQ(ierr); 8975 PetscFunctionReturn(0); 8976 } 8977 8978 #undef __FUNCT__ 8979 #define __FUNCT__ "MatFactorSolveSchurComplementTranspose" 8980 /*@ 8981 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 8982 8983 Logically Collective on Mat 8984 8985 Input Parameters: 8986 + F - the factored matrix obtained by calling MatGetFactor() 8987 . rhs - location where the right hand side of the Schur complement system is stored 8988 - sol - location where the solution of the Schur complement system has to be returned 8989 8990 Notes: 8991 The sizes of the vectors should match the size of the Schur complement 8992 8993 Level: advanced 8994 8995 References: 8996 8997 .seealso: MatGetFactor(), MatFactorSetSchurIS() 8998 @*/ 8999 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9000 { 9001 PetscErrorCode ierr; 9002 9003 PetscFunctionBegin; 9004 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9005 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9006 PetscValidHeaderSpecific(sol,VEC_CLASSID,2); 9007 PetscCheckSameComm(F,1,rhs,2); 9008 PetscCheckSameComm(F,1,sol,3); 9009 ierr = PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));CHKERRQ(ierr); 9010 PetscFunctionReturn(0); 9011 } 9012 9013 #undef __FUNCT__ 9014 #define __FUNCT__ "MatFactorSolveSchurComplement" 9015 /*@ 9016 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9017 9018 Logically Collective on Mat 9019 9020 Input Parameters: 9021 + F - the factored matrix obtained by calling MatGetFactor() 9022 . rhs - location where the right hand side of the Schur complement system is stored 9023 - sol - location where the solution of the Schur complement system has to be returned 9024 9025 Notes: 9026 The sizes of the vectors should match the size of the Schur complement 9027 9028 Level: advanced 9029 9030 References: 9031 9032 .seealso: MatGetFactor(), MatFactorSetSchurIS() 9033 @*/ 9034 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9035 { 9036 PetscErrorCode ierr; 9037 9038 PetscFunctionBegin; 9039 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9040 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9041 PetscValidHeaderSpecific(sol,VEC_CLASSID,2); 9042 PetscCheckSameComm(F,1,rhs,2); 9043 PetscCheckSameComm(F,1,sol,3); 9044 ierr = PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));CHKERRQ(ierr); 9045 PetscFunctionReturn(0); 9046 } 9047 9048 #undef __FUNCT__ 9049 #define __FUNCT__ "MatFactorInvertSchurComplement" 9050 /*@ 9051 MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step 9052 9053 Logically Collective on Mat 9054 9055 Input Parameters: 9056 + F - the factored matrix obtained by calling MatGetFactor() 9057 9058 Notes: 9059 9060 Level: advanced 9061 9062 References: 9063 9064 .seealso: MatGetFactor(), MatFactorSetSchurIS() 9065 @*/ 9066 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9067 { 9068 PetscErrorCode ierr; 9069 9070 PetscFunctionBegin; 9071 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9072 ierr = PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));CHKERRQ(ierr); 9073 PetscFunctionReturn(0); 9074 } 9075 9076 9077 #undef __FUNCT__ 9078 #define __FUNCT__ "MatPtAP" 9079 /*@ 9080 MatPtAP - Creates the matrix product C = P^T * A * P 9081 9082 Neighbor-wise Collective on Mat 9083 9084 Input Parameters: 9085 + A - the matrix 9086 . P - the projection matrix 9087 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9088 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9089 if the result is a dense matrix this is irrelevent 9090 9091 Output Parameters: 9092 . C - the product matrix 9093 9094 Notes: 9095 C will be created and must be destroyed by the user with MatDestroy(). 9096 9097 This routine is currently only implemented for pairs of AIJ matrices and classes 9098 which inherit from AIJ. 9099 9100 Level: intermediate 9101 9102 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9103 @*/ 9104 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9105 { 9106 PetscErrorCode ierr; 9107 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9108 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9109 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9110 PetscBool viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE; 9111 9112 PetscFunctionBegin; 9113 ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);CHKERRQ(ierr); 9114 ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);CHKERRQ(ierr); 9115 9116 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9117 PetscValidType(A,1); 9118 MatCheckPreallocated(A,1); 9119 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9120 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9121 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9122 PetscValidType(P,2); 9123 MatCheckPreallocated(P,2); 9124 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9125 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9126 9127 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); 9128 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); 9129 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9130 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9131 9132 if (scall == MAT_REUSE_MATRIX) { 9133 PetscValidPointer(*C,5); 9134 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9135 if (viatranspose || viamatmatmatmult) { 9136 Mat Pt; 9137 ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr); 9138 if (viamatmatmatmult) { 9139 ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr); 9140 } else { 9141 Mat AP; 9142 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr); 9143 ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr); 9144 ierr = MatDestroy(&AP);CHKERRQ(ierr); 9145 } 9146 ierr = MatDestroy(&Pt);CHKERRQ(ierr); 9147 } else { 9148 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9149 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9150 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9151 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9152 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9153 } 9154 PetscFunctionReturn(0); 9155 } 9156 9157 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9158 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9159 9160 fA = A->ops->ptap; 9161 fP = P->ops->ptap; 9162 if (fP == fA) { 9163 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name); 9164 ptap = fA; 9165 } else { 9166 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9167 char ptapname[256]; 9168 ierr = PetscStrcpy(ptapname,"MatPtAP_");CHKERRQ(ierr); 9169 ierr = PetscStrcat(ptapname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9170 ierr = PetscStrcat(ptapname,"_");CHKERRQ(ierr); 9171 ierr = PetscStrcat(ptapname,((PetscObject)P)->type_name);CHKERRQ(ierr); 9172 ierr = PetscStrcat(ptapname,"_C");CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9173 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9174 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); 9175 } 9176 9177 if (viatranspose || viamatmatmatmult) { 9178 Mat Pt; 9179 ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr); 9180 if (viamatmatmatmult) { 9181 ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr); 9182 ierr = PetscInfo(*C,"MatPtAP via MatMatMatMult\n");CHKERRQ(ierr); 9183 } else { 9184 Mat AP; 9185 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr); 9186 ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr); 9187 ierr = MatDestroy(&AP);CHKERRQ(ierr); 9188 ierr = PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");CHKERRQ(ierr); 9189 } 9190 ierr = MatDestroy(&Pt);CHKERRQ(ierr); 9191 } else { 9192 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9193 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9194 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9195 } 9196 PetscFunctionReturn(0); 9197 } 9198 9199 #undef __FUNCT__ 9200 #define __FUNCT__ "MatPtAPNumeric" 9201 /*@ 9202 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9203 9204 Neighbor-wise Collective on Mat 9205 9206 Input Parameters: 9207 + A - the matrix 9208 - P - the projection matrix 9209 9210 Output Parameters: 9211 . C - the product matrix 9212 9213 Notes: 9214 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9215 the user using MatDeatroy(). 9216 9217 This routine is currently only implemented for pairs of AIJ matrices and classes 9218 which inherit from AIJ. C will be of type MATAIJ. 9219 9220 Level: intermediate 9221 9222 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9223 @*/ 9224 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9225 { 9226 PetscErrorCode ierr; 9227 9228 PetscFunctionBegin; 9229 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9230 PetscValidType(A,1); 9231 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9232 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9233 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9234 PetscValidType(P,2); 9235 MatCheckPreallocated(P,2); 9236 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9237 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9238 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9239 PetscValidType(C,3); 9240 MatCheckPreallocated(C,3); 9241 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9242 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); 9243 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); 9244 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); 9245 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); 9246 MatCheckPreallocated(A,1); 9247 9248 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9249 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9250 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9251 PetscFunctionReturn(0); 9252 } 9253 9254 #undef __FUNCT__ 9255 #define __FUNCT__ "MatPtAPSymbolic" 9256 /*@ 9257 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9258 9259 Neighbor-wise Collective on Mat 9260 9261 Input Parameters: 9262 + A - the matrix 9263 - P - the projection matrix 9264 9265 Output Parameters: 9266 . C - the (i,j) structure of the product matrix 9267 9268 Notes: 9269 C will be created and must be destroyed by the user with MatDestroy(). 9270 9271 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9272 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9273 this (i,j) structure by calling MatPtAPNumeric(). 9274 9275 Level: intermediate 9276 9277 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9278 @*/ 9279 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9280 { 9281 PetscErrorCode ierr; 9282 9283 PetscFunctionBegin; 9284 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9285 PetscValidType(A,1); 9286 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9287 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9288 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9289 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9290 PetscValidType(P,2); 9291 MatCheckPreallocated(P,2); 9292 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9293 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9294 PetscValidPointer(C,3); 9295 9296 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); 9297 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); 9298 MatCheckPreallocated(A,1); 9299 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9300 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9301 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9302 9303 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9304 PetscFunctionReturn(0); 9305 } 9306 9307 #undef __FUNCT__ 9308 #define __FUNCT__ "MatRARt" 9309 /*@ 9310 MatRARt - Creates the matrix product C = R * A * R^T 9311 9312 Neighbor-wise Collective on Mat 9313 9314 Input Parameters: 9315 + A - the matrix 9316 . R - the projection matrix 9317 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9318 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9319 if the result is a dense matrix this is irrelevent 9320 9321 Output Parameters: 9322 . C - the product matrix 9323 9324 Notes: 9325 C will be created and must be destroyed by the user with MatDestroy(). 9326 9327 This routine is currently only implemented for pairs of AIJ matrices and classes 9328 which inherit from AIJ. 9329 9330 Level: intermediate 9331 9332 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9333 @*/ 9334 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9335 { 9336 PetscErrorCode ierr; 9337 9338 PetscFunctionBegin; 9339 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9340 PetscValidType(A,1); 9341 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9342 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9343 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9344 PetscValidType(R,2); 9345 MatCheckPreallocated(R,2); 9346 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9347 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9348 PetscValidPointer(C,3); 9349 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); 9350 9351 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9352 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9353 MatCheckPreallocated(A,1); 9354 9355 if (!A->ops->rart) { 9356 MatType mattype; 9357 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 9358 SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype); 9359 } 9360 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9361 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9362 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9363 PetscFunctionReturn(0); 9364 } 9365 9366 #undef __FUNCT__ 9367 #define __FUNCT__ "MatRARtNumeric" 9368 /*@ 9369 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9370 9371 Neighbor-wise Collective on Mat 9372 9373 Input Parameters: 9374 + A - the matrix 9375 - R - the projection matrix 9376 9377 Output Parameters: 9378 . C - the product matrix 9379 9380 Notes: 9381 C must have been created by calling MatRARtSymbolic and must be destroyed by 9382 the user using MatDestroy(). 9383 9384 This routine is currently only implemented for pairs of AIJ matrices and classes 9385 which inherit from AIJ. C will be of type MATAIJ. 9386 9387 Level: intermediate 9388 9389 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9390 @*/ 9391 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9392 { 9393 PetscErrorCode ierr; 9394 9395 PetscFunctionBegin; 9396 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9397 PetscValidType(A,1); 9398 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9399 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9400 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9401 PetscValidType(R,2); 9402 MatCheckPreallocated(R,2); 9403 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9404 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9405 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9406 PetscValidType(C,3); 9407 MatCheckPreallocated(C,3); 9408 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9409 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); 9410 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); 9411 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); 9412 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); 9413 MatCheckPreallocated(A,1); 9414 9415 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9416 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9417 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9418 PetscFunctionReturn(0); 9419 } 9420 9421 #undef __FUNCT__ 9422 #define __FUNCT__ "MatRARtSymbolic" 9423 /*@ 9424 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9425 9426 Neighbor-wise Collective on Mat 9427 9428 Input Parameters: 9429 + A - the matrix 9430 - R - the projection matrix 9431 9432 Output Parameters: 9433 . C - the (i,j) structure of the product matrix 9434 9435 Notes: 9436 C will be created and must be destroyed by the user with MatDestroy(). 9437 9438 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9439 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9440 this (i,j) structure by calling MatRARtNumeric(). 9441 9442 Level: intermediate 9443 9444 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9445 @*/ 9446 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9447 { 9448 PetscErrorCode ierr; 9449 9450 PetscFunctionBegin; 9451 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9452 PetscValidType(A,1); 9453 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9454 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9455 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9456 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9457 PetscValidType(R,2); 9458 MatCheckPreallocated(R,2); 9459 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9460 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9461 PetscValidPointer(C,3); 9462 9463 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); 9464 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); 9465 MatCheckPreallocated(A,1); 9466 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9467 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9468 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9469 9470 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9471 PetscFunctionReturn(0); 9472 } 9473 9474 #undef __FUNCT__ 9475 #define __FUNCT__ "MatMatMult" 9476 /*@ 9477 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9478 9479 Neighbor-wise Collective on Mat 9480 9481 Input Parameters: 9482 + A - the left matrix 9483 . B - the right matrix 9484 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9485 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9486 if the result is a dense matrix this is irrelevent 9487 9488 Output Parameters: 9489 . C - the product matrix 9490 9491 Notes: 9492 Unless scall is MAT_REUSE_MATRIX C will be created. 9493 9494 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9495 9496 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9497 actually needed. 9498 9499 If you have many matrices with the same non-zero structure to multiply, you 9500 should either 9501 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9502 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9503 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 9504 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9505 9506 Level: intermediate 9507 9508 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9509 @*/ 9510 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9511 { 9512 PetscErrorCode ierr; 9513 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9514 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9515 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9516 9517 PetscFunctionBegin; 9518 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9519 PetscValidType(A,1); 9520 MatCheckPreallocated(A,1); 9521 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9522 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9523 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9524 PetscValidType(B,2); 9525 MatCheckPreallocated(B,2); 9526 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9527 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9528 PetscValidPointer(C,3); 9529 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); 9530 if (scall == MAT_REUSE_MATRIX) { 9531 PetscValidPointer(*C,5); 9532 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9533 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9534 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9535 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9536 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9537 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9538 PetscFunctionReturn(0); 9539 } 9540 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9541 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9542 9543 fA = A->ops->matmult; 9544 fB = B->ops->matmult; 9545 if (fB == fA) { 9546 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 9547 mult = fB; 9548 } else { 9549 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9550 char multname[256]; 9551 ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr); 9552 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9553 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 9554 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 9555 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9556 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9557 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); 9558 } 9559 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9560 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9561 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9562 PetscFunctionReturn(0); 9563 } 9564 9565 #undef __FUNCT__ 9566 #define __FUNCT__ "MatMatMultSymbolic" 9567 /*@ 9568 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9569 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9570 9571 Neighbor-wise Collective on Mat 9572 9573 Input Parameters: 9574 + A - the left matrix 9575 . B - the right matrix 9576 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9577 if C is a dense matrix this is irrelevent 9578 9579 Output Parameters: 9580 . C - the product matrix 9581 9582 Notes: 9583 Unless scall is MAT_REUSE_MATRIX C will be created. 9584 9585 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9586 actually needed. 9587 9588 This routine is currently implemented for 9589 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9590 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9591 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9592 9593 Level: intermediate 9594 9595 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173 9596 We should incorporate them into PETSc. 9597 9598 .seealso: MatMatMult(), MatMatMultNumeric() 9599 @*/ 9600 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9601 { 9602 PetscErrorCode ierr; 9603 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9604 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9605 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9606 9607 PetscFunctionBegin; 9608 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9609 PetscValidType(A,1); 9610 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9611 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9612 9613 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9614 PetscValidType(B,2); 9615 MatCheckPreallocated(B,2); 9616 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9617 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9618 PetscValidPointer(C,3); 9619 9620 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); 9621 if (fill == PETSC_DEFAULT) fill = 2.0; 9622 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9623 MatCheckPreallocated(A,1); 9624 9625 Asymbolic = A->ops->matmultsymbolic; 9626 Bsymbolic = B->ops->matmultsymbolic; 9627 if (Asymbolic == Bsymbolic) { 9628 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 9629 symbolic = Bsymbolic; 9630 } else { /* dispatch based on the type of A and B */ 9631 char symbolicname[256]; 9632 ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr); 9633 ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9634 ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr); 9635 ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr); 9636 ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr); 9637 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9638 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); 9639 } 9640 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9641 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 9642 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9643 PetscFunctionReturn(0); 9644 } 9645 9646 #undef __FUNCT__ 9647 #define __FUNCT__ "MatMatMultNumeric" 9648 /*@ 9649 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9650 Call this routine after first calling MatMatMultSymbolic(). 9651 9652 Neighbor-wise Collective on Mat 9653 9654 Input Parameters: 9655 + A - the left matrix 9656 - B - the right matrix 9657 9658 Output Parameters: 9659 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9660 9661 Notes: 9662 C must have been created with MatMatMultSymbolic(). 9663 9664 This routine is currently implemented for 9665 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9666 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9667 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9668 9669 Level: intermediate 9670 9671 .seealso: MatMatMult(), MatMatMultSymbolic() 9672 @*/ 9673 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9674 { 9675 PetscErrorCode ierr; 9676 9677 PetscFunctionBegin; 9678 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 9679 PetscFunctionReturn(0); 9680 } 9681 9682 #undef __FUNCT__ 9683 #define __FUNCT__ "MatMatTransposeMult" 9684 /*@ 9685 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9686 9687 Neighbor-wise Collective on Mat 9688 9689 Input Parameters: 9690 + A - the left matrix 9691 . B - the right matrix 9692 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9693 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9694 9695 Output Parameters: 9696 . C - the product matrix 9697 9698 Notes: 9699 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9700 9701 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9702 9703 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9704 actually needed. 9705 9706 This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ. 9707 9708 Level: intermediate 9709 9710 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9711 @*/ 9712 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9713 { 9714 PetscErrorCode ierr; 9715 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9716 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9717 9718 PetscFunctionBegin; 9719 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9720 PetscValidType(A,1); 9721 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9722 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9723 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9724 PetscValidType(B,2); 9725 MatCheckPreallocated(B,2); 9726 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9727 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9728 PetscValidPointer(C,3); 9729 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); 9730 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9731 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9732 MatCheckPreallocated(A,1); 9733 9734 fA = A->ops->mattransposemult; 9735 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9736 fB = B->ops->mattransposemult; 9737 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9738 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); 9739 9740 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9741 if (scall == MAT_INITIAL_MATRIX) { 9742 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9743 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9744 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9745 } 9746 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9747 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 9748 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9749 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9750 PetscFunctionReturn(0); 9751 } 9752 9753 #undef __FUNCT__ 9754 #define __FUNCT__ "MatTransposeMatMult" 9755 /*@ 9756 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9757 9758 Neighbor-wise Collective on Mat 9759 9760 Input Parameters: 9761 + A - the left matrix 9762 . B - the right matrix 9763 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9764 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9765 9766 Output Parameters: 9767 . C - the product matrix 9768 9769 Notes: 9770 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9771 9772 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9773 9774 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9775 actually needed. 9776 9777 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9778 which inherit from SeqAIJ. C will be of same type as the input matrices. 9779 9780 Level: intermediate 9781 9782 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 9783 @*/ 9784 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9785 { 9786 PetscErrorCode ierr; 9787 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9788 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9789 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 9790 9791 PetscFunctionBegin; 9792 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9793 PetscValidType(A,1); 9794 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9795 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9796 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9797 PetscValidType(B,2); 9798 MatCheckPreallocated(B,2); 9799 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9800 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9801 PetscValidPointer(C,3); 9802 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); 9803 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9804 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9805 MatCheckPreallocated(A,1); 9806 9807 fA = A->ops->transposematmult; 9808 fB = B->ops->transposematmult; 9809 if (fB==fA) { 9810 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9811 transposematmult = fA; 9812 } else { 9813 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9814 char multname[256]; 9815 ierr = PetscStrcpy(multname,"MatTransposeMatMult_");CHKERRQ(ierr); 9816 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9817 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 9818 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 9819 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9820 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 9821 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); 9822 } 9823 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9824 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 9825 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9826 PetscFunctionReturn(0); 9827 } 9828 9829 #undef __FUNCT__ 9830 #define __FUNCT__ "MatMatMatMult" 9831 /*@ 9832 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9833 9834 Neighbor-wise Collective on Mat 9835 9836 Input Parameters: 9837 + A - the left matrix 9838 . B - the middle matrix 9839 . C - the right matrix 9840 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9841 - 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 9842 if the result is a dense matrix this is irrelevent 9843 9844 Output Parameters: 9845 . D - the product matrix 9846 9847 Notes: 9848 Unless scall is MAT_REUSE_MATRIX D will be created. 9849 9850 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9851 9852 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9853 actually needed. 9854 9855 If you have many matrices with the same non-zero structure to multiply, you 9856 should use MAT_REUSE_MATRIX in all calls but the first or 9857 9858 Level: intermediate 9859 9860 .seealso: MatMatMult, MatPtAP() 9861 @*/ 9862 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9863 { 9864 PetscErrorCode ierr; 9865 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9866 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9867 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9868 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9869 9870 PetscFunctionBegin; 9871 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9872 PetscValidType(A,1); 9873 MatCheckPreallocated(A,1); 9874 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9875 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9876 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9877 PetscValidType(B,2); 9878 MatCheckPreallocated(B,2); 9879 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9880 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9881 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9882 PetscValidPointer(C,3); 9883 MatCheckPreallocated(C,3); 9884 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9885 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9886 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); 9887 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); 9888 if (scall == MAT_REUSE_MATRIX) { 9889 PetscValidPointer(*D,6); 9890 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 9891 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9892 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9893 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9894 PetscFunctionReturn(0); 9895 } 9896 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9897 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9898 9899 fA = A->ops->matmatmult; 9900 fB = B->ops->matmatmult; 9901 fC = C->ops->matmatmult; 9902 if (fA == fB && fA == fC) { 9903 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9904 mult = fA; 9905 } else { 9906 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 9907 char multname[256]; 9908 ierr = PetscStrcpy(multname,"MatMatMatMult_");CHKERRQ(ierr); 9909 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9910 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 9911 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 9912 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 9913 ierr = PetscStrcat(multname,((PetscObject)C)->type_name);CHKERRQ(ierr); 9914 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); 9915 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9916 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); 9917 } 9918 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9919 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9920 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9921 PetscFunctionReturn(0); 9922 } 9923 9924 #undef __FUNCT__ 9925 #define __FUNCT__ "MatCreateRedundantMatrix" 9926 /*@C 9927 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9928 9929 Collective on Mat 9930 9931 Input Parameters: 9932 + mat - the matrix 9933 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9934 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 9935 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9936 9937 Output Parameter: 9938 . matredundant - redundant matrix 9939 9940 Notes: 9941 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9942 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9943 9944 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 9945 calling it. 9946 9947 Level: advanced 9948 9949 Concepts: subcommunicator 9950 Concepts: duplicate matrix 9951 9952 .seealso: MatDestroy() 9953 @*/ 9954 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 9955 { 9956 PetscErrorCode ierr; 9957 MPI_Comm comm; 9958 PetscMPIInt size; 9959 PetscInt mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 9960 Mat_Redundant *redund=NULL; 9961 PetscSubcomm psubcomm=NULL; 9962 MPI_Comm subcomm_in=subcomm; 9963 Mat *matseq; 9964 IS isrow,iscol; 9965 PetscBool newsubcomm=PETSC_FALSE; 9966 9967 PetscFunctionBegin; 9968 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 9969 if (size == 1 || nsubcomm == 1) { 9970 if (reuse == MAT_INITIAL_MATRIX) { 9971 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 9972 } else { 9973 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 9974 } 9975 PetscFunctionReturn(0); 9976 } 9977 9978 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9979 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 9980 PetscValidPointer(*matredundant,5); 9981 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 9982 } 9983 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9984 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9985 MatCheckPreallocated(mat,1); 9986 9987 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 9988 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 9989 /* create psubcomm, then get subcomm */ 9990 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 9991 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 9992 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 9993 9994 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 9995 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 9996 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 9997 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 9998 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 9999 newsubcomm = PETSC_TRUE; 10000 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10001 } 10002 10003 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10004 if (reuse == MAT_INITIAL_MATRIX) { 10005 mloc_sub = PETSC_DECIDE; 10006 if (bs < 1) { 10007 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10008 } else { 10009 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10010 } 10011 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10012 rstart = rend - mloc_sub; 10013 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10014 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10015 } else { /* reuse == MAT_REUSE_MATRIX */ 10016 /* retrieve subcomm */ 10017 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10018 redund = (*matredundant)->redundant; 10019 isrow = redund->isrow; 10020 iscol = redund->iscol; 10021 matseq = redund->matseq; 10022 } 10023 ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10024 10025 /* get matredundant over subcomm */ 10026 if (reuse == MAT_INITIAL_MATRIX) { 10027 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);CHKERRQ(ierr); 10028 10029 /* create a supporting struct and attach it to C for reuse */ 10030 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10031 (*matredundant)->redundant = redund; 10032 redund->isrow = isrow; 10033 redund->iscol = iscol; 10034 redund->matseq = matseq; 10035 if (newsubcomm) { 10036 redund->subcomm = subcomm; 10037 } else { 10038 redund->subcomm = MPI_COMM_NULL; 10039 } 10040 } else { 10041 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10042 } 10043 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10044 PetscFunctionReturn(0); 10045 } 10046 10047 #undef __FUNCT__ 10048 #define __FUNCT__ "MatGetMultiProcBlock" 10049 /*@C 10050 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10051 a given 'mat' object. Each submatrix can span multiple procs. 10052 10053 Collective on Mat 10054 10055 Input Parameters: 10056 + mat - the matrix 10057 . subcomm - the subcommunicator obtained by com_split(comm) 10058 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10059 10060 Output Parameter: 10061 . subMat - 'parallel submatrices each spans a given subcomm 10062 10063 Notes: 10064 The submatrix partition across processors is dictated by 'subComm' a 10065 communicator obtained by com_split(comm). The comm_split 10066 is not restriced to be grouped with consecutive original ranks. 10067 10068 Due the comm_split() usage, the parallel layout of the submatrices 10069 map directly to the layout of the original matrix [wrt the local 10070 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10071 into the 'DiagonalMat' of the subMat, hence it is used directly from 10072 the subMat. However the offDiagMat looses some columns - and this is 10073 reconstructed with MatSetValues() 10074 10075 Level: advanced 10076 10077 Concepts: subcommunicator 10078 Concepts: submatrices 10079 10080 .seealso: MatGetSubMatrices() 10081 @*/ 10082 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10083 { 10084 PetscErrorCode ierr; 10085 PetscMPIInt commsize,subCommSize; 10086 10087 PetscFunctionBegin; 10088 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10089 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10090 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10091 10092 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10093 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10094 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10095 PetscFunctionReturn(0); 10096 } 10097 10098 #undef __FUNCT__ 10099 #define __FUNCT__ "MatGetLocalSubMatrix" 10100 /*@ 10101 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10102 10103 Not Collective 10104 10105 Input Arguments: 10106 mat - matrix to extract local submatrix from 10107 isrow - local row indices for submatrix 10108 iscol - local column indices for submatrix 10109 10110 Output Arguments: 10111 submat - the submatrix 10112 10113 Level: intermediate 10114 10115 Notes: 10116 The submat should be returned with MatRestoreLocalSubMatrix(). 10117 10118 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10119 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10120 10121 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10122 MatSetValuesBlockedLocal() will also be implemented. 10123 10124 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10125 matrices obtained with DMCreateMat() generally already have the local to global mapping provided. 10126 10127 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10128 @*/ 10129 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10130 { 10131 PetscErrorCode ierr; 10132 10133 PetscFunctionBegin; 10134 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10135 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10136 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10137 PetscCheckSameComm(isrow,2,iscol,3); 10138 PetscValidPointer(submat,4); 10139 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10140 10141 if (mat->ops->getlocalsubmatrix) { 10142 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10143 } else { 10144 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10145 } 10146 PetscFunctionReturn(0); 10147 } 10148 10149 #undef __FUNCT__ 10150 #define __FUNCT__ "MatRestoreLocalSubMatrix" 10151 /*@ 10152 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10153 10154 Not Collective 10155 10156 Input Arguments: 10157 mat - matrix to extract local submatrix from 10158 isrow - local row indices for submatrix 10159 iscol - local column indices for submatrix 10160 submat - the submatrix 10161 10162 Level: intermediate 10163 10164 .seealso: MatGetLocalSubMatrix() 10165 @*/ 10166 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10167 { 10168 PetscErrorCode ierr; 10169 10170 PetscFunctionBegin; 10171 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10172 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10173 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10174 PetscCheckSameComm(isrow,2,iscol,3); 10175 PetscValidPointer(submat,4); 10176 if (*submat) { 10177 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10178 } 10179 10180 if (mat->ops->restorelocalsubmatrix) { 10181 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10182 } else { 10183 ierr = MatDestroy(submat);CHKERRQ(ierr); 10184 } 10185 *submat = NULL; 10186 PetscFunctionReturn(0); 10187 } 10188 10189 /* --------------------------------------------------------*/ 10190 #undef __FUNCT__ 10191 #define __FUNCT__ "MatFindZeroDiagonals" 10192 /*@ 10193 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix 10194 10195 Collective on Mat 10196 10197 Input Parameter: 10198 . mat - the matrix 10199 10200 Output Parameter: 10201 . is - if any rows have zero diagonals this contains the list of them 10202 10203 Level: developer 10204 10205 Concepts: matrix-vector product 10206 10207 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10208 @*/ 10209 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10210 { 10211 PetscErrorCode ierr; 10212 10213 PetscFunctionBegin; 10214 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10215 PetscValidType(mat,1); 10216 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10217 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10218 10219 if (!mat->ops->findzerodiagonals) { 10220 Vec diag; 10221 const PetscScalar *a; 10222 PetscInt *rows; 10223 PetscInt rStart, rEnd, r, nrow = 0; 10224 10225 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10226 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10227 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10228 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10229 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10230 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10231 nrow = 0; 10232 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10233 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10234 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10235 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10236 } else { 10237 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10238 } 10239 PetscFunctionReturn(0); 10240 } 10241 10242 #undef __FUNCT__ 10243 #define __FUNCT__ "MatFindOffBlockDiagonalEntries" 10244 /*@ 10245 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10246 10247 Collective on Mat 10248 10249 Input Parameter: 10250 . mat - the matrix 10251 10252 Output Parameter: 10253 . is - contains the list of rows with off block diagonal entries 10254 10255 Level: developer 10256 10257 Concepts: matrix-vector product 10258 10259 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10260 @*/ 10261 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10262 { 10263 PetscErrorCode ierr; 10264 10265 PetscFunctionBegin; 10266 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10267 PetscValidType(mat,1); 10268 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10269 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10270 10271 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10272 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10273 PetscFunctionReturn(0); 10274 } 10275 10276 #undef __FUNCT__ 10277 #define __FUNCT__ "MatInvertBlockDiagonal" 10278 /*@C 10279 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10280 10281 Collective on Mat 10282 10283 Input Parameters: 10284 . mat - the matrix 10285 10286 Output Parameters: 10287 . values - the block inverses in column major order (FORTRAN-like) 10288 10289 Note: 10290 This routine is not available from Fortran. 10291 10292 Level: advanced 10293 @*/ 10294 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10295 { 10296 PetscErrorCode ierr; 10297 10298 PetscFunctionBegin; 10299 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10300 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10301 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10302 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10303 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10304 PetscFunctionReturn(0); 10305 } 10306 10307 #undef __FUNCT__ 10308 #define __FUNCT__ "MatTransposeColoringDestroy" 10309 /*@C 10310 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10311 via MatTransposeColoringCreate(). 10312 10313 Collective on MatTransposeColoring 10314 10315 Input Parameter: 10316 . c - coloring context 10317 10318 Level: intermediate 10319 10320 .seealso: MatTransposeColoringCreate() 10321 @*/ 10322 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10323 { 10324 PetscErrorCode ierr; 10325 MatTransposeColoring matcolor=*c; 10326 10327 PetscFunctionBegin; 10328 if (!matcolor) PetscFunctionReturn(0); 10329 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10330 10331 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10332 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10333 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10334 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10335 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10336 if (matcolor->brows>0) { 10337 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10338 } 10339 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10340 PetscFunctionReturn(0); 10341 } 10342 10343 #undef __FUNCT__ 10344 #define __FUNCT__ "MatTransColoringApplySpToDen" 10345 /*@C 10346 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10347 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10348 MatTransposeColoring to sparse B. 10349 10350 Collective on MatTransposeColoring 10351 10352 Input Parameters: 10353 + B - sparse matrix B 10354 . Btdense - symbolic dense matrix B^T 10355 - coloring - coloring context created with MatTransposeColoringCreate() 10356 10357 Output Parameter: 10358 . Btdense - dense matrix B^T 10359 10360 Options Database Keys: 10361 + -mat_transpose_coloring_view - Activates basic viewing or coloring 10362 . -mat_transpose_coloring_view_draw - Activates drawing of coloring 10363 - -mat_transpose_coloring_view_info - Activates viewing of coloring info 10364 10365 Level: intermediate 10366 10367 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy() 10368 10369 .keywords: coloring 10370 @*/ 10371 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10372 { 10373 PetscErrorCode ierr; 10374 10375 PetscFunctionBegin; 10376 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10377 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10378 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10379 10380 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10381 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10382 PetscFunctionReturn(0); 10383 } 10384 10385 #undef __FUNCT__ 10386 #define __FUNCT__ "MatTransColoringApplyDenToSp" 10387 /*@C 10388 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10389 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10390 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10391 Csp from Cden. 10392 10393 Collective on MatTransposeColoring 10394 10395 Input Parameters: 10396 + coloring - coloring context created with MatTransposeColoringCreate() 10397 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10398 10399 Output Parameter: 10400 . Csp - sparse matrix 10401 10402 Options Database Keys: 10403 + -mat_multtranspose_coloring_view - Activates basic viewing or coloring 10404 . -mat_multtranspose_coloring_view_draw - Activates drawing of coloring 10405 - -mat_multtranspose_coloring_view_info - Activates viewing of coloring info 10406 10407 Level: intermediate 10408 10409 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10410 10411 .keywords: coloring 10412 @*/ 10413 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10414 { 10415 PetscErrorCode ierr; 10416 10417 PetscFunctionBegin; 10418 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10419 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10420 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10421 10422 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10423 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10424 PetscFunctionReturn(0); 10425 } 10426 10427 #undef __FUNCT__ 10428 #define __FUNCT__ "MatTransposeColoringCreate" 10429 /*@C 10430 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10431 10432 Collective on Mat 10433 10434 Input Parameters: 10435 + mat - the matrix product C 10436 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10437 10438 Output Parameter: 10439 . color - the new coloring context 10440 10441 Level: intermediate 10442 10443 .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(), 10444 MatTransColoringApplyDenToSp(), MatTransposeColoringView(), 10445 @*/ 10446 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10447 { 10448 MatTransposeColoring c; 10449 MPI_Comm comm; 10450 PetscErrorCode ierr; 10451 10452 PetscFunctionBegin; 10453 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10454 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10455 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10456 10457 c->ctype = iscoloring->ctype; 10458 if (mat->ops->transposecoloringcreate) { 10459 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10460 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10461 10462 *color = c; 10463 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10464 PetscFunctionReturn(0); 10465 } 10466 10467 #undef __FUNCT__ 10468 #define __FUNCT__ "MatGetNonzeroState" 10469 /*@ 10470 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10471 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10472 same, otherwise it will be larger 10473 10474 Not Collective 10475 10476 Input Parameter: 10477 . A - the matrix 10478 10479 Output Parameter: 10480 . state - the current state 10481 10482 Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10483 different matrices 10484 10485 Level: intermediate 10486 10487 @*/ 10488 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10489 { 10490 PetscFunctionBegin; 10491 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10492 *state = mat->nonzerostate; 10493 PetscFunctionReturn(0); 10494 } 10495 10496 #undef __FUNCT__ 10497 #define __FUNCT__ "MatCreateMPIMatConcatenateSeqMat" 10498 /*@ 10499 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10500 matrices from each processor 10501 10502 Collective on MPI_Comm 10503 10504 Input Parameters: 10505 + comm - the communicators the parallel matrix will live on 10506 . seqmat - the input sequential matrices 10507 . n - number of local columns (or PETSC_DECIDE) 10508 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10509 10510 Output Parameter: 10511 . mpimat - the parallel matrix generated 10512 10513 Level: advanced 10514 10515 Notes: The number of columns of the matrix in EACH processor MUST be the same. 10516 10517 @*/ 10518 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10519 { 10520 PetscErrorCode ierr; 10521 PetscMPIInt size; 10522 10523 PetscFunctionBegin; 10524 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10525 if (size == 1) { 10526 if (reuse == MAT_INITIAL_MATRIX) { 10527 ierr = MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat);CHKERRQ(ierr); 10528 } else { 10529 ierr = MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10530 } 10531 PetscFunctionReturn(0); 10532 } 10533 10534 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10535 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10536 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10537 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10538 PetscFunctionReturn(0); 10539 } 10540 10541 #undef __FUNCT__ 10542 #define __FUNCT__ "MatSubdomainsCreateCoalesce" 10543 /*@ 10544 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10545 ranks' ownership ranges. 10546 10547 Collective on A 10548 10549 Input Parameters: 10550 + A - the matrix to create subdomains from 10551 - N - requested number of subdomains 10552 10553 10554 Output Parameters: 10555 + n - number of subdomains resulting on this rank 10556 - iss - IS list with indices of subdomains on this rank 10557 10558 Level: advanced 10559 10560 Notes: number of subdomains must be smaller than the communicator size 10561 @*/ 10562 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10563 { 10564 MPI_Comm comm,subcomm; 10565 PetscMPIInt size,rank,color; 10566 PetscInt rstart,rend,k; 10567 PetscErrorCode ierr; 10568 10569 PetscFunctionBegin; 10570 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10571 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10572 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10573 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); 10574 *n = 1; 10575 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10576 color = rank/k; 10577 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10578 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10579 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10580 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10581 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10582 PetscFunctionReturn(0); 10583 } 10584