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 of the transpose of 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 Concepts: null space^attaching to matrix 8146 8147 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8148 @*/ 8149 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8150 { 8151 PetscFunctionBegin; 8152 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8153 PetscValidType(mat,1); 8154 PetscValidPointer(nullsp,2); 8155 *nullsp = mat->transnullsp; 8156 PetscFunctionReturn(0); 8157 } 8158 8159 #undef __FUNCT__ 8160 #define __FUNCT__ "MatSetTransposeNullSpace" 8161 /*@ 8162 MatSetTransposeNullSpace - attaches a null space to a matrix. 8163 8164 Logically Collective on Mat and MatNullSpace 8165 8166 Input Parameters: 8167 + mat - the matrix 8168 - nullsp - the null space object 8169 8170 Level: advanced 8171 8172 Notes: 8173 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. 8174 You must also call MatSetNullSpace() 8175 8176 8177 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8178 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). 8179 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 8180 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 8181 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). 8182 8183 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8184 8185 Concepts: null space^attaching to matrix 8186 8187 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8188 @*/ 8189 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8190 { 8191 PetscErrorCode ierr; 8192 8193 PetscFunctionBegin; 8194 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8195 PetscValidType(mat,1); 8196 PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8197 MatCheckPreallocated(mat,1); 8198 ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr); 8199 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8200 mat->transnullsp = nullsp; 8201 PetscFunctionReturn(0); 8202 } 8203 8204 #undef __FUNCT__ 8205 #define __FUNCT__ "MatSetNearNullSpace" 8206 /*@ 8207 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8208 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8209 8210 Logically Collective on Mat and MatNullSpace 8211 8212 Input Parameters: 8213 + mat - the matrix 8214 - nullsp - the null space object 8215 8216 Level: advanced 8217 8218 Notes: 8219 Overwrites any previous near null space that may have been attached 8220 8221 You can remove the null space by calling this routine with an nullsp of NULL 8222 8223 Concepts: null space^attaching to matrix 8224 8225 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8226 @*/ 8227 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8228 { 8229 PetscErrorCode ierr; 8230 8231 PetscFunctionBegin; 8232 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8233 PetscValidType(mat,1); 8234 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8235 MatCheckPreallocated(mat,1); 8236 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8237 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8238 mat->nearnullsp = nullsp; 8239 PetscFunctionReturn(0); 8240 } 8241 8242 #undef __FUNCT__ 8243 #define __FUNCT__ "MatGetNearNullSpace" 8244 /*@ 8245 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8246 8247 Not Collective 8248 8249 Input Parameters: 8250 . mat - the matrix 8251 8252 Output Parameters: 8253 . nullsp - the null space object, NULL if not set 8254 8255 Level: developer 8256 8257 Concepts: null space^attaching to matrix 8258 8259 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8260 @*/ 8261 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8262 { 8263 PetscFunctionBegin; 8264 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8265 PetscValidType(mat,1); 8266 PetscValidPointer(nullsp,2); 8267 MatCheckPreallocated(mat,1); 8268 *nullsp = mat->nearnullsp; 8269 PetscFunctionReturn(0); 8270 } 8271 8272 #undef __FUNCT__ 8273 #define __FUNCT__ "MatICCFactor" 8274 /*@C 8275 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8276 8277 Collective on Mat 8278 8279 Input Parameters: 8280 + mat - the matrix 8281 . row - row/column permutation 8282 . fill - expected fill factor >= 1.0 8283 - level - level of fill, for ICC(k) 8284 8285 Notes: 8286 Probably really in-place only when level of fill is zero, otherwise allocates 8287 new space to store factored matrix and deletes previous memory. 8288 8289 Most users should employ the simplified KSP interface for linear solvers 8290 instead of working directly with matrix algebra routines such as this. 8291 See, e.g., KSPCreate(). 8292 8293 Level: developer 8294 8295 Concepts: matrices^incomplete Cholesky factorization 8296 Concepts: Cholesky factorization 8297 8298 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8299 8300 Developer Note: fortran interface is not autogenerated as the f90 8301 interface defintion cannot be generated correctly [due to MatFactorInfo] 8302 8303 @*/ 8304 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8305 { 8306 PetscErrorCode ierr; 8307 8308 PetscFunctionBegin; 8309 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8310 PetscValidType(mat,1); 8311 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8312 PetscValidPointer(info,3); 8313 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8314 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8315 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8316 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8317 MatCheckPreallocated(mat,1); 8318 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8319 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8320 PetscFunctionReturn(0); 8321 } 8322 8323 #undef __FUNCT__ 8324 #define __FUNCT__ "MatSetValuesAdifor" 8325 /*@ 8326 MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix. 8327 8328 Not Collective 8329 8330 Input Parameters: 8331 + mat - the matrix 8332 . nl - leading dimension of v 8333 - v - the values compute with ADIFOR 8334 8335 Level: developer 8336 8337 Notes: 8338 Must call MatSetColoring() before using this routine. Also this matrix must already 8339 have its nonzero pattern determined. 8340 8341 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 8342 MatSetValues(), MatSetColoring() 8343 @*/ 8344 PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v) 8345 { 8346 PetscErrorCode ierr; 8347 8348 PetscFunctionBegin; 8349 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8350 PetscValidType(mat,1); 8351 PetscValidPointer(v,3); 8352 8353 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8354 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 8355 if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8356 ierr = (*mat->ops->setvaluesadifor)(mat,nl,v);CHKERRQ(ierr); 8357 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 8358 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8359 PetscFunctionReturn(0); 8360 } 8361 8362 #undef __FUNCT__ 8363 #define __FUNCT__ "MatDiagonalScaleLocal" 8364 /*@ 8365 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8366 ghosted ones. 8367 8368 Not Collective 8369 8370 Input Parameters: 8371 + mat - the matrix 8372 - diag = the diagonal values, including ghost ones 8373 8374 Level: developer 8375 8376 Notes: Works only for MPIAIJ and MPIBAIJ matrices 8377 8378 .seealso: MatDiagonalScale() 8379 @*/ 8380 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8381 { 8382 PetscErrorCode ierr; 8383 PetscMPIInt size; 8384 8385 PetscFunctionBegin; 8386 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8387 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8388 PetscValidType(mat,1); 8389 8390 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8391 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8392 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8393 if (size == 1) { 8394 PetscInt n,m; 8395 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8396 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8397 if (m == n) { 8398 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8399 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8400 } else { 8401 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8402 } 8403 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8404 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8405 PetscFunctionReturn(0); 8406 } 8407 8408 #undef __FUNCT__ 8409 #define __FUNCT__ "MatGetInertia" 8410 /*@ 8411 MatGetInertia - Gets the inertia from a factored matrix 8412 8413 Collective on Mat 8414 8415 Input Parameter: 8416 . mat - the matrix 8417 8418 Output Parameters: 8419 + nneg - number of negative eigenvalues 8420 . nzero - number of zero eigenvalues 8421 - npos - number of positive eigenvalues 8422 8423 Level: advanced 8424 8425 Notes: Matrix must have been factored by MatCholeskyFactor() 8426 8427 8428 @*/ 8429 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8430 { 8431 PetscErrorCode ierr; 8432 8433 PetscFunctionBegin; 8434 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8435 PetscValidType(mat,1); 8436 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8437 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8438 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8439 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8440 PetscFunctionReturn(0); 8441 } 8442 8443 /* ----------------------------------------------------------------*/ 8444 #undef __FUNCT__ 8445 #define __FUNCT__ "MatSolves" 8446 /*@C 8447 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8448 8449 Neighbor-wise Collective on Mat and Vecs 8450 8451 Input Parameters: 8452 + mat - the factored matrix 8453 - b - the right-hand-side vectors 8454 8455 Output Parameter: 8456 . x - the result vectors 8457 8458 Notes: 8459 The vectors b and x cannot be the same. I.e., one cannot 8460 call MatSolves(A,x,x). 8461 8462 Notes: 8463 Most users should employ the simplified KSP interface for linear solvers 8464 instead of working directly with matrix algebra routines such as this. 8465 See, e.g., KSPCreate(). 8466 8467 Level: developer 8468 8469 Concepts: matrices^triangular solves 8470 8471 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8472 @*/ 8473 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8474 { 8475 PetscErrorCode ierr; 8476 8477 PetscFunctionBegin; 8478 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8479 PetscValidType(mat,1); 8480 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8481 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8482 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8483 8484 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8485 MatCheckPreallocated(mat,1); 8486 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8487 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8488 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8489 PetscFunctionReturn(0); 8490 } 8491 8492 #undef __FUNCT__ 8493 #define __FUNCT__ "MatIsSymmetric" 8494 /*@ 8495 MatIsSymmetric - Test whether a matrix is symmetric 8496 8497 Collective on Mat 8498 8499 Input Parameter: 8500 + A - the matrix to test 8501 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8502 8503 Output Parameters: 8504 . flg - the result 8505 8506 Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8507 8508 Level: intermediate 8509 8510 Concepts: matrix^symmetry 8511 8512 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8513 @*/ 8514 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8515 { 8516 PetscErrorCode ierr; 8517 8518 PetscFunctionBegin; 8519 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8520 PetscValidPointer(flg,2); 8521 8522 if (!A->symmetric_set) { 8523 if (!A->ops->issymmetric) { 8524 MatType mattype; 8525 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8526 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8527 } 8528 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8529 if (!tol) { 8530 A->symmetric_set = PETSC_TRUE; 8531 A->symmetric = *flg; 8532 if (A->symmetric) { 8533 A->structurally_symmetric_set = PETSC_TRUE; 8534 A->structurally_symmetric = PETSC_TRUE; 8535 } 8536 } 8537 } else if (A->symmetric) { 8538 *flg = PETSC_TRUE; 8539 } else if (!tol) { 8540 *flg = PETSC_FALSE; 8541 } else { 8542 if (!A->ops->issymmetric) { 8543 MatType mattype; 8544 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8545 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8546 } 8547 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8548 } 8549 PetscFunctionReturn(0); 8550 } 8551 8552 #undef __FUNCT__ 8553 #define __FUNCT__ "MatIsHermitian" 8554 /*@ 8555 MatIsHermitian - Test whether a matrix is Hermitian 8556 8557 Collective on Mat 8558 8559 Input Parameter: 8560 + A - the matrix to test 8561 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8562 8563 Output Parameters: 8564 . flg - the result 8565 8566 Level: intermediate 8567 8568 Concepts: matrix^symmetry 8569 8570 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8571 MatIsSymmetricKnown(), MatIsSymmetric() 8572 @*/ 8573 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8574 { 8575 PetscErrorCode ierr; 8576 8577 PetscFunctionBegin; 8578 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8579 PetscValidPointer(flg,2); 8580 8581 if (!A->hermitian_set) { 8582 if (!A->ops->ishermitian) { 8583 MatType mattype; 8584 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8585 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8586 } 8587 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8588 if (!tol) { 8589 A->hermitian_set = PETSC_TRUE; 8590 A->hermitian = *flg; 8591 if (A->hermitian) { 8592 A->structurally_symmetric_set = PETSC_TRUE; 8593 A->structurally_symmetric = PETSC_TRUE; 8594 } 8595 } 8596 } else if (A->hermitian) { 8597 *flg = PETSC_TRUE; 8598 } else if (!tol) { 8599 *flg = PETSC_FALSE; 8600 } else { 8601 if (!A->ops->ishermitian) { 8602 MatType mattype; 8603 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8604 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8605 } 8606 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8607 } 8608 PetscFunctionReturn(0); 8609 } 8610 8611 #undef __FUNCT__ 8612 #define __FUNCT__ "MatIsSymmetricKnown" 8613 /*@ 8614 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8615 8616 Not Collective 8617 8618 Input Parameter: 8619 . A - the matrix to check 8620 8621 Output Parameters: 8622 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8623 - flg - the result 8624 8625 Level: advanced 8626 8627 Concepts: matrix^symmetry 8628 8629 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8630 if you want it explicitly checked 8631 8632 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8633 @*/ 8634 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8635 { 8636 PetscFunctionBegin; 8637 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8638 PetscValidPointer(set,2); 8639 PetscValidPointer(flg,3); 8640 if (A->symmetric_set) { 8641 *set = PETSC_TRUE; 8642 *flg = A->symmetric; 8643 } else { 8644 *set = PETSC_FALSE; 8645 } 8646 PetscFunctionReturn(0); 8647 } 8648 8649 #undef __FUNCT__ 8650 #define __FUNCT__ "MatIsHermitianKnown" 8651 /*@ 8652 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8653 8654 Not Collective 8655 8656 Input Parameter: 8657 . A - the matrix to check 8658 8659 Output Parameters: 8660 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8661 - flg - the result 8662 8663 Level: advanced 8664 8665 Concepts: matrix^symmetry 8666 8667 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8668 if you want it explicitly checked 8669 8670 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8671 @*/ 8672 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8673 { 8674 PetscFunctionBegin; 8675 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8676 PetscValidPointer(set,2); 8677 PetscValidPointer(flg,3); 8678 if (A->hermitian_set) { 8679 *set = PETSC_TRUE; 8680 *flg = A->hermitian; 8681 } else { 8682 *set = PETSC_FALSE; 8683 } 8684 PetscFunctionReturn(0); 8685 } 8686 8687 #undef __FUNCT__ 8688 #define __FUNCT__ "MatIsStructurallySymmetric" 8689 /*@ 8690 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8691 8692 Collective on Mat 8693 8694 Input Parameter: 8695 . A - the matrix to test 8696 8697 Output Parameters: 8698 . flg - the result 8699 8700 Level: intermediate 8701 8702 Concepts: matrix^symmetry 8703 8704 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8705 @*/ 8706 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8707 { 8708 PetscErrorCode ierr; 8709 8710 PetscFunctionBegin; 8711 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8712 PetscValidPointer(flg,2); 8713 if (!A->structurally_symmetric_set) { 8714 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8715 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8716 8717 A->structurally_symmetric_set = PETSC_TRUE; 8718 } 8719 *flg = A->structurally_symmetric; 8720 PetscFunctionReturn(0); 8721 } 8722 8723 #undef __FUNCT__ 8724 #define __FUNCT__ "MatStashGetInfo" 8725 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*); 8726 /*@ 8727 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8728 to be communicated to other processors during the MatAssemblyBegin/End() process 8729 8730 Not collective 8731 8732 Input Parameter: 8733 . vec - the vector 8734 8735 Output Parameters: 8736 + nstash - the size of the stash 8737 . reallocs - the number of additional mallocs incurred. 8738 . bnstash - the size of the block stash 8739 - breallocs - the number of additional mallocs incurred.in the block stash 8740 8741 Level: advanced 8742 8743 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8744 8745 @*/ 8746 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8747 { 8748 PetscErrorCode ierr; 8749 8750 PetscFunctionBegin; 8751 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8752 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8753 PetscFunctionReturn(0); 8754 } 8755 8756 #undef __FUNCT__ 8757 #define __FUNCT__ "MatCreateVecs" 8758 /*@C 8759 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8760 parallel layout 8761 8762 Collective on Mat 8763 8764 Input Parameter: 8765 . mat - the matrix 8766 8767 Output Parameter: 8768 + right - (optional) vector that the matrix can be multiplied against 8769 - left - (optional) vector that the matrix vector product can be stored in 8770 8771 Notes: 8772 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(). 8773 8774 Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8775 8776 Level: advanced 8777 8778 .seealso: MatCreate(), VecDestroy() 8779 @*/ 8780 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8781 { 8782 PetscErrorCode ierr; 8783 8784 PetscFunctionBegin; 8785 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8786 PetscValidType(mat,1); 8787 if (mat->ops->getvecs) { 8788 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8789 } else { 8790 PetscInt rbs,cbs; 8791 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8792 if (right) { 8793 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8794 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8795 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8796 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8797 ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr); 8798 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8799 } 8800 if (left) { 8801 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8802 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8803 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8804 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8805 ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr); 8806 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8807 } 8808 } 8809 PetscFunctionReturn(0); 8810 } 8811 8812 #undef __FUNCT__ 8813 #define __FUNCT__ "MatFactorInfoInitialize" 8814 /*@C 8815 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8816 with default values. 8817 8818 Not Collective 8819 8820 Input Parameters: 8821 . info - the MatFactorInfo data structure 8822 8823 8824 Notes: The solvers are generally used through the KSP and PC objects, for example 8825 PCLU, PCILU, PCCHOLESKY, PCICC 8826 8827 Level: developer 8828 8829 .seealso: MatFactorInfo 8830 8831 Developer Note: fortran interface is not autogenerated as the f90 8832 interface defintion cannot be generated correctly [due to MatFactorInfo] 8833 8834 @*/ 8835 8836 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8837 { 8838 PetscErrorCode ierr; 8839 8840 PetscFunctionBegin; 8841 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8842 PetscFunctionReturn(0); 8843 } 8844 8845 #undef __FUNCT__ 8846 #define __FUNCT__ "MatFactorSetSchurIS" 8847 /*@ 8848 MatFactorSetSchurIS - Set indices corresponding to the Schur complement 8849 8850 Collective on Mat 8851 8852 Input Parameters: 8853 + mat - the factored matrix 8854 - is - the index set defining the Schur indices (0-based) 8855 8856 Notes: 8857 8858 Level: developer 8859 8860 Concepts: 8861 8862 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement() 8863 8864 @*/ 8865 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 8866 { 8867 PetscErrorCode ierr,(*f)(Mat,IS); 8868 8869 PetscFunctionBegin; 8870 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8871 PetscValidType(mat,1); 8872 PetscValidHeaderSpecific(is,IS_CLASSID,2); 8873 PetscValidType(is,2); 8874 PetscCheckSameComm(mat,1,is,2); 8875 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 8876 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 8877 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"); 8878 ierr = (*f)(mat,is);CHKERRQ(ierr); 8879 PetscFunctionReturn(0); 8880 } 8881 8882 #undef __FUNCT__ 8883 #define __FUNCT__ "MatFactorCreateSchurComplement" 8884 /*@ 8885 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 8886 8887 Logically Collective on Mat 8888 8889 Input Parameters: 8890 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 8891 . *S - location where to return the Schur complement (MATDENSE) 8892 8893 Notes: 8894 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. 8895 If MatFactorInvertSchurComplement has been called, the routine gets back the inverse 8896 8897 Level: advanced 8898 8899 References: 8900 8901 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement() 8902 @*/ 8903 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S) 8904 { 8905 PetscErrorCode ierr; 8906 8907 PetscFunctionBegin; 8908 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8909 ierr = PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*),(F,S));CHKERRQ(ierr); 8910 PetscFunctionReturn(0); 8911 } 8912 8913 #undef __FUNCT__ 8914 #define __FUNCT__ "MatFactorGetSchurComplement" 8915 /*@ 8916 MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data 8917 8918 Logically Collective on Mat 8919 8920 Input Parameters: 8921 + F - the factored matrix obtained by calling MatGetFactor() 8922 . *S - location where to return the Schur complement (in MATDENSE format) 8923 8924 Notes: 8925 Schur complement mode is currently implemented for sequential matrices. 8926 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. 8927 The caller should call MatFactorRestoreSchurComplement when the object is no longer needed. 8928 8929 Level: advanced 8930 8931 References: 8932 8933 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement() 8934 @*/ 8935 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S) 8936 { 8937 PetscErrorCode ierr; 8938 8939 PetscFunctionBegin; 8940 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8941 ierr = PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*),(F,S));CHKERRQ(ierr); 8942 PetscFunctionReturn(0); 8943 } 8944 8945 #undef __FUNCT__ 8946 #define __FUNCT__ "MatFactorRestoreSchurComplement" 8947 /*@ 8948 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 8949 8950 Logically Collective on Mat 8951 8952 Input Parameters: 8953 + F - the factored matrix obtained by calling MatGetFactor() 8954 . *S - location where the Schur complement is stored 8955 8956 Notes: 8957 8958 Level: advanced 8959 8960 References: 8961 8962 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement() 8963 @*/ 8964 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S) 8965 { 8966 PetscErrorCode ierr; 8967 8968 PetscFunctionBegin; 8969 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8970 PetscValidHeaderSpecific(*S,MAT_CLASSID,1); 8971 ierr = MatDestroy(S);CHKERRQ(ierr); 8972 PetscFunctionReturn(0); 8973 } 8974 8975 #undef __FUNCT__ 8976 #define __FUNCT__ "MatFactorSolveSchurComplementTranspose" 8977 /*@ 8978 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 8979 8980 Logically Collective on Mat 8981 8982 Input Parameters: 8983 + F - the factored matrix obtained by calling MatGetFactor() 8984 . rhs - location where the right hand side of the Schur complement system is stored 8985 - sol - location where the solution of the Schur complement system has to be returned 8986 8987 Notes: 8988 The sizes of the vectors should match the size of the Schur complement 8989 8990 Level: advanced 8991 8992 References: 8993 8994 .seealso: MatGetFactor(), MatFactorSetSchurIS() 8995 @*/ 8996 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 8997 { 8998 PetscErrorCode ierr; 8999 9000 PetscFunctionBegin; 9001 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9002 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9003 PetscValidHeaderSpecific(sol,VEC_CLASSID,2); 9004 PetscCheckSameComm(F,1,rhs,2); 9005 PetscCheckSameComm(F,1,sol,3); 9006 ierr = PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));CHKERRQ(ierr); 9007 PetscFunctionReturn(0); 9008 } 9009 9010 #undef __FUNCT__ 9011 #define __FUNCT__ "MatFactorSolveSchurComplement" 9012 /*@ 9013 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9014 9015 Logically Collective on Mat 9016 9017 Input Parameters: 9018 + F - the factored matrix obtained by calling MatGetFactor() 9019 . rhs - location where the right hand side of the Schur complement system is stored 9020 - sol - location where the solution of the Schur complement system has to be returned 9021 9022 Notes: 9023 The sizes of the vectors should match the size of the Schur complement 9024 9025 Level: advanced 9026 9027 References: 9028 9029 .seealso: MatGetFactor(), MatFactorSetSchurIS() 9030 @*/ 9031 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9032 { 9033 PetscErrorCode ierr; 9034 9035 PetscFunctionBegin; 9036 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9037 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9038 PetscValidHeaderSpecific(sol,VEC_CLASSID,2); 9039 PetscCheckSameComm(F,1,rhs,2); 9040 PetscCheckSameComm(F,1,sol,3); 9041 ierr = PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));CHKERRQ(ierr); 9042 PetscFunctionReturn(0); 9043 } 9044 9045 #undef __FUNCT__ 9046 #define __FUNCT__ "MatFactorInvertSchurComplement" 9047 /*@ 9048 MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step 9049 9050 Logically Collective on Mat 9051 9052 Input Parameters: 9053 + F - the factored matrix obtained by calling MatGetFactor() 9054 9055 Notes: 9056 9057 Level: advanced 9058 9059 References: 9060 9061 .seealso: MatGetFactor(), MatFactorSetSchurIS() 9062 @*/ 9063 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9064 { 9065 PetscErrorCode ierr; 9066 9067 PetscFunctionBegin; 9068 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9069 ierr = PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));CHKERRQ(ierr); 9070 PetscFunctionReturn(0); 9071 } 9072 9073 9074 #undef __FUNCT__ 9075 #define __FUNCT__ "MatPtAP" 9076 /*@ 9077 MatPtAP - Creates the matrix product C = P^T * A * P 9078 9079 Neighbor-wise Collective on Mat 9080 9081 Input Parameters: 9082 + A - the matrix 9083 . P - the projection matrix 9084 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9085 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9086 if the result is a dense matrix this is irrelevent 9087 9088 Output Parameters: 9089 . C - the product matrix 9090 9091 Notes: 9092 C will be created and must be destroyed by the user with MatDestroy(). 9093 9094 This routine is currently only implemented for pairs of AIJ matrices and classes 9095 which inherit from AIJ. 9096 9097 Level: intermediate 9098 9099 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9100 @*/ 9101 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9102 { 9103 PetscErrorCode ierr; 9104 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9105 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9106 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9107 PetscBool viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE; 9108 9109 PetscFunctionBegin; 9110 ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);CHKERRQ(ierr); 9111 ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);CHKERRQ(ierr); 9112 9113 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9114 PetscValidType(A,1); 9115 MatCheckPreallocated(A,1); 9116 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9117 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9118 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9119 PetscValidType(P,2); 9120 MatCheckPreallocated(P,2); 9121 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9122 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9123 9124 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); 9125 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); 9126 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9127 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9128 9129 if (scall == MAT_REUSE_MATRIX) { 9130 PetscValidPointer(*C,5); 9131 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9132 if (viatranspose || viamatmatmatmult) { 9133 Mat Pt; 9134 ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr); 9135 if (viamatmatmatmult) { 9136 ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr); 9137 } else { 9138 Mat AP; 9139 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr); 9140 ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr); 9141 ierr = MatDestroy(&AP);CHKERRQ(ierr); 9142 } 9143 ierr = MatDestroy(&Pt);CHKERRQ(ierr); 9144 } else { 9145 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9146 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9147 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9148 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9149 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9150 } 9151 PetscFunctionReturn(0); 9152 } 9153 9154 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9155 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9156 9157 fA = A->ops->ptap; 9158 fP = P->ops->ptap; 9159 if (fP == fA) { 9160 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name); 9161 ptap = fA; 9162 } else { 9163 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9164 char ptapname[256]; 9165 ierr = PetscStrcpy(ptapname,"MatPtAP_");CHKERRQ(ierr); 9166 ierr = PetscStrcat(ptapname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9167 ierr = PetscStrcat(ptapname,"_");CHKERRQ(ierr); 9168 ierr = PetscStrcat(ptapname,((PetscObject)P)->type_name);CHKERRQ(ierr); 9169 ierr = PetscStrcat(ptapname,"_C");CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9170 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9171 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); 9172 } 9173 9174 if (viatranspose || viamatmatmatmult) { 9175 Mat Pt; 9176 ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr); 9177 if (viamatmatmatmult) { 9178 ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr); 9179 ierr = PetscInfo(*C,"MatPtAP via MatMatMatMult\n");CHKERRQ(ierr); 9180 } else { 9181 Mat AP; 9182 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr); 9183 ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr); 9184 ierr = MatDestroy(&AP);CHKERRQ(ierr); 9185 ierr = PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");CHKERRQ(ierr); 9186 } 9187 ierr = MatDestroy(&Pt);CHKERRQ(ierr); 9188 } else { 9189 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9190 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9191 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9192 } 9193 PetscFunctionReturn(0); 9194 } 9195 9196 #undef __FUNCT__ 9197 #define __FUNCT__ "MatPtAPNumeric" 9198 /*@ 9199 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9200 9201 Neighbor-wise Collective on Mat 9202 9203 Input Parameters: 9204 + A - the matrix 9205 - P - the projection matrix 9206 9207 Output Parameters: 9208 . C - the product matrix 9209 9210 Notes: 9211 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9212 the user using MatDeatroy(). 9213 9214 This routine is currently only implemented for pairs of AIJ matrices and classes 9215 which inherit from AIJ. C will be of type MATAIJ. 9216 9217 Level: intermediate 9218 9219 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9220 @*/ 9221 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9222 { 9223 PetscErrorCode ierr; 9224 9225 PetscFunctionBegin; 9226 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9227 PetscValidType(A,1); 9228 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9229 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9230 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9231 PetscValidType(P,2); 9232 MatCheckPreallocated(P,2); 9233 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9234 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9235 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9236 PetscValidType(C,3); 9237 MatCheckPreallocated(C,3); 9238 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9239 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); 9240 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); 9241 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); 9242 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); 9243 MatCheckPreallocated(A,1); 9244 9245 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9246 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9247 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9248 PetscFunctionReturn(0); 9249 } 9250 9251 #undef __FUNCT__ 9252 #define __FUNCT__ "MatPtAPSymbolic" 9253 /*@ 9254 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9255 9256 Neighbor-wise Collective on Mat 9257 9258 Input Parameters: 9259 + A - the matrix 9260 - P - the projection matrix 9261 9262 Output Parameters: 9263 . C - the (i,j) structure of the product matrix 9264 9265 Notes: 9266 C will be created and must be destroyed by the user with MatDestroy(). 9267 9268 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9269 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9270 this (i,j) structure by calling MatPtAPNumeric(). 9271 9272 Level: intermediate 9273 9274 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9275 @*/ 9276 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9277 { 9278 PetscErrorCode ierr; 9279 9280 PetscFunctionBegin; 9281 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9282 PetscValidType(A,1); 9283 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9284 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9285 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9286 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9287 PetscValidType(P,2); 9288 MatCheckPreallocated(P,2); 9289 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9290 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9291 PetscValidPointer(C,3); 9292 9293 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); 9294 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); 9295 MatCheckPreallocated(A,1); 9296 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9297 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9298 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9299 9300 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9301 PetscFunctionReturn(0); 9302 } 9303 9304 #undef __FUNCT__ 9305 #define __FUNCT__ "MatRARt" 9306 /*@ 9307 MatRARt - Creates the matrix product C = R * A * R^T 9308 9309 Neighbor-wise Collective on Mat 9310 9311 Input Parameters: 9312 + A - the matrix 9313 . R - the projection matrix 9314 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9315 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9316 if the result is a dense matrix this is irrelevent 9317 9318 Output Parameters: 9319 . C - the product matrix 9320 9321 Notes: 9322 C will be created and must be destroyed by the user with MatDestroy(). 9323 9324 This routine is currently only implemented for pairs of AIJ matrices and classes 9325 which inherit from AIJ. 9326 9327 Level: intermediate 9328 9329 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9330 @*/ 9331 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9332 { 9333 PetscErrorCode ierr; 9334 9335 PetscFunctionBegin; 9336 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9337 PetscValidType(A,1); 9338 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9339 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9340 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9341 PetscValidType(R,2); 9342 MatCheckPreallocated(R,2); 9343 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9344 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9345 PetscValidPointer(C,3); 9346 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); 9347 9348 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9349 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9350 MatCheckPreallocated(A,1); 9351 9352 if (!A->ops->rart) { 9353 MatType mattype; 9354 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 9355 SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype); 9356 } 9357 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9358 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9359 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9360 PetscFunctionReturn(0); 9361 } 9362 9363 #undef __FUNCT__ 9364 #define __FUNCT__ "MatRARtNumeric" 9365 /*@ 9366 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9367 9368 Neighbor-wise Collective on Mat 9369 9370 Input Parameters: 9371 + A - the matrix 9372 - R - the projection matrix 9373 9374 Output Parameters: 9375 . C - the product matrix 9376 9377 Notes: 9378 C must have been created by calling MatRARtSymbolic and must be destroyed by 9379 the user using MatDestroy(). 9380 9381 This routine is currently only implemented for pairs of AIJ matrices and classes 9382 which inherit from AIJ. C will be of type MATAIJ. 9383 9384 Level: intermediate 9385 9386 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9387 @*/ 9388 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9389 { 9390 PetscErrorCode ierr; 9391 9392 PetscFunctionBegin; 9393 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9394 PetscValidType(A,1); 9395 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9396 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9397 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9398 PetscValidType(R,2); 9399 MatCheckPreallocated(R,2); 9400 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9401 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9402 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9403 PetscValidType(C,3); 9404 MatCheckPreallocated(C,3); 9405 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9406 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); 9407 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); 9408 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); 9409 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); 9410 MatCheckPreallocated(A,1); 9411 9412 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9413 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9414 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9415 PetscFunctionReturn(0); 9416 } 9417 9418 #undef __FUNCT__ 9419 #define __FUNCT__ "MatRARtSymbolic" 9420 /*@ 9421 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9422 9423 Neighbor-wise Collective on Mat 9424 9425 Input Parameters: 9426 + A - the matrix 9427 - R - the projection matrix 9428 9429 Output Parameters: 9430 . C - the (i,j) structure of the product matrix 9431 9432 Notes: 9433 C will be created and must be destroyed by the user with MatDestroy(). 9434 9435 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9436 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9437 this (i,j) structure by calling MatRARtNumeric(). 9438 9439 Level: intermediate 9440 9441 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9442 @*/ 9443 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9444 { 9445 PetscErrorCode ierr; 9446 9447 PetscFunctionBegin; 9448 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9449 PetscValidType(A,1); 9450 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9451 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9452 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9453 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9454 PetscValidType(R,2); 9455 MatCheckPreallocated(R,2); 9456 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9457 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9458 PetscValidPointer(C,3); 9459 9460 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); 9461 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); 9462 MatCheckPreallocated(A,1); 9463 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9464 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9465 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9466 9467 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9468 PetscFunctionReturn(0); 9469 } 9470 9471 #undef __FUNCT__ 9472 #define __FUNCT__ "MatMatMult" 9473 /*@ 9474 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9475 9476 Neighbor-wise Collective on Mat 9477 9478 Input Parameters: 9479 + A - the left matrix 9480 . B - the right matrix 9481 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9482 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9483 if the result is a dense matrix this is irrelevent 9484 9485 Output Parameters: 9486 . C - the product matrix 9487 9488 Notes: 9489 Unless scall is MAT_REUSE_MATRIX C will be created. 9490 9491 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9492 9493 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9494 actually needed. 9495 9496 If you have many matrices with the same non-zero structure to multiply, you 9497 should either 9498 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9499 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9500 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 9501 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9502 9503 Level: intermediate 9504 9505 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9506 @*/ 9507 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9508 { 9509 PetscErrorCode ierr; 9510 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9511 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9512 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9513 9514 PetscFunctionBegin; 9515 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9516 PetscValidType(A,1); 9517 MatCheckPreallocated(A,1); 9518 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9519 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9520 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9521 PetscValidType(B,2); 9522 MatCheckPreallocated(B,2); 9523 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9524 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9525 PetscValidPointer(C,3); 9526 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); 9527 if (scall == MAT_REUSE_MATRIX) { 9528 PetscValidPointer(*C,5); 9529 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9530 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9531 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9532 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9533 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9534 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9535 PetscFunctionReturn(0); 9536 } 9537 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9538 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9539 9540 fA = A->ops->matmult; 9541 fB = B->ops->matmult; 9542 if (fB == fA) { 9543 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 9544 mult = fB; 9545 } else { 9546 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9547 char multname[256]; 9548 ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr); 9549 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9550 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 9551 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 9552 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9553 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9554 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); 9555 } 9556 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9557 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9558 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9559 PetscFunctionReturn(0); 9560 } 9561 9562 #undef __FUNCT__ 9563 #define __FUNCT__ "MatMatMultSymbolic" 9564 /*@ 9565 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9566 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9567 9568 Neighbor-wise Collective on Mat 9569 9570 Input Parameters: 9571 + A - the left matrix 9572 . B - the right matrix 9573 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9574 if C is a dense matrix this is irrelevent 9575 9576 Output Parameters: 9577 . C - the product matrix 9578 9579 Notes: 9580 Unless scall is MAT_REUSE_MATRIX C will be created. 9581 9582 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9583 actually needed. 9584 9585 This routine is currently implemented for 9586 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9587 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9588 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9589 9590 Level: intermediate 9591 9592 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173 9593 We should incorporate them into PETSc. 9594 9595 .seealso: MatMatMult(), MatMatMultNumeric() 9596 @*/ 9597 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9598 { 9599 PetscErrorCode ierr; 9600 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9601 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9602 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9603 9604 PetscFunctionBegin; 9605 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9606 PetscValidType(A,1); 9607 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9608 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9609 9610 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9611 PetscValidType(B,2); 9612 MatCheckPreallocated(B,2); 9613 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9614 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9615 PetscValidPointer(C,3); 9616 9617 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); 9618 if (fill == PETSC_DEFAULT) fill = 2.0; 9619 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9620 MatCheckPreallocated(A,1); 9621 9622 Asymbolic = A->ops->matmultsymbolic; 9623 Bsymbolic = B->ops->matmultsymbolic; 9624 if (Asymbolic == Bsymbolic) { 9625 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 9626 symbolic = Bsymbolic; 9627 } else { /* dispatch based on the type of A and B */ 9628 char symbolicname[256]; 9629 ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr); 9630 ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9631 ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr); 9632 ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr); 9633 ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr); 9634 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9635 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); 9636 } 9637 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9638 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 9639 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9640 PetscFunctionReturn(0); 9641 } 9642 9643 #undef __FUNCT__ 9644 #define __FUNCT__ "MatMatMultNumeric" 9645 /*@ 9646 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9647 Call this routine after first calling MatMatMultSymbolic(). 9648 9649 Neighbor-wise Collective on Mat 9650 9651 Input Parameters: 9652 + A - the left matrix 9653 - B - the right matrix 9654 9655 Output Parameters: 9656 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9657 9658 Notes: 9659 C must have been created with MatMatMultSymbolic(). 9660 9661 This routine is currently implemented for 9662 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9663 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9664 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9665 9666 Level: intermediate 9667 9668 .seealso: MatMatMult(), MatMatMultSymbolic() 9669 @*/ 9670 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9671 { 9672 PetscErrorCode ierr; 9673 9674 PetscFunctionBegin; 9675 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 9676 PetscFunctionReturn(0); 9677 } 9678 9679 #undef __FUNCT__ 9680 #define __FUNCT__ "MatMatTransposeMult" 9681 /*@ 9682 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9683 9684 Neighbor-wise Collective on Mat 9685 9686 Input Parameters: 9687 + A - the left matrix 9688 . B - the right matrix 9689 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9690 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9691 9692 Output Parameters: 9693 . C - the product matrix 9694 9695 Notes: 9696 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9697 9698 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9699 9700 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9701 actually needed. 9702 9703 This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ. 9704 9705 Level: intermediate 9706 9707 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9708 @*/ 9709 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9710 { 9711 PetscErrorCode ierr; 9712 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9713 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9714 9715 PetscFunctionBegin; 9716 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9717 PetscValidType(A,1); 9718 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9719 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9720 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9721 PetscValidType(B,2); 9722 MatCheckPreallocated(B,2); 9723 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9724 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9725 PetscValidPointer(C,3); 9726 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); 9727 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9728 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9729 MatCheckPreallocated(A,1); 9730 9731 fA = A->ops->mattransposemult; 9732 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9733 fB = B->ops->mattransposemult; 9734 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9735 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); 9736 9737 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9738 if (scall == MAT_INITIAL_MATRIX) { 9739 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9740 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9741 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9742 } 9743 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9744 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 9745 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9746 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9747 PetscFunctionReturn(0); 9748 } 9749 9750 #undef __FUNCT__ 9751 #define __FUNCT__ "MatTransposeMatMult" 9752 /*@ 9753 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9754 9755 Neighbor-wise Collective on Mat 9756 9757 Input Parameters: 9758 + A - the left matrix 9759 . B - the right matrix 9760 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9761 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9762 9763 Output Parameters: 9764 . C - the product matrix 9765 9766 Notes: 9767 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9768 9769 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9770 9771 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9772 actually needed. 9773 9774 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9775 which inherit from SeqAIJ. C will be of same type as the input matrices. 9776 9777 Level: intermediate 9778 9779 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 9780 @*/ 9781 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9782 { 9783 PetscErrorCode ierr; 9784 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9785 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9786 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 9787 9788 PetscFunctionBegin; 9789 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9790 PetscValidType(A,1); 9791 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9792 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9793 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9794 PetscValidType(B,2); 9795 MatCheckPreallocated(B,2); 9796 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9797 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9798 PetscValidPointer(C,3); 9799 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); 9800 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9801 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9802 MatCheckPreallocated(A,1); 9803 9804 fA = A->ops->transposematmult; 9805 fB = B->ops->transposematmult; 9806 if (fB==fA) { 9807 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9808 transposematmult = fA; 9809 } else { 9810 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9811 char multname[256]; 9812 ierr = PetscStrcpy(multname,"MatTransposeMatMult_");CHKERRQ(ierr); 9813 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9814 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 9815 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 9816 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9817 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 9818 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); 9819 } 9820 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9821 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 9822 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9823 PetscFunctionReturn(0); 9824 } 9825 9826 #undef __FUNCT__ 9827 #define __FUNCT__ "MatMatMatMult" 9828 /*@ 9829 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9830 9831 Neighbor-wise Collective on Mat 9832 9833 Input Parameters: 9834 + A - the left matrix 9835 . B - the middle matrix 9836 . C - the right matrix 9837 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9838 - 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 9839 if the result is a dense matrix this is irrelevent 9840 9841 Output Parameters: 9842 . D - the product matrix 9843 9844 Notes: 9845 Unless scall is MAT_REUSE_MATRIX D will be created. 9846 9847 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9848 9849 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9850 actually needed. 9851 9852 If you have many matrices with the same non-zero structure to multiply, you 9853 should use MAT_REUSE_MATRIX in all calls but the first or 9854 9855 Level: intermediate 9856 9857 .seealso: MatMatMult, MatPtAP() 9858 @*/ 9859 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9860 { 9861 PetscErrorCode ierr; 9862 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9863 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9864 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9865 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9866 9867 PetscFunctionBegin; 9868 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9869 PetscValidType(A,1); 9870 MatCheckPreallocated(A,1); 9871 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9872 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9873 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9874 PetscValidType(B,2); 9875 MatCheckPreallocated(B,2); 9876 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9877 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9878 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9879 PetscValidPointer(C,3); 9880 MatCheckPreallocated(C,3); 9881 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9882 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9883 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); 9884 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); 9885 if (scall == MAT_REUSE_MATRIX) { 9886 PetscValidPointer(*D,6); 9887 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 9888 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9889 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9890 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9891 PetscFunctionReturn(0); 9892 } 9893 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9894 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9895 9896 fA = A->ops->matmatmult; 9897 fB = B->ops->matmatmult; 9898 fC = C->ops->matmatmult; 9899 if (fA == fB && fA == fC) { 9900 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9901 mult = fA; 9902 } else { 9903 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 9904 char multname[256]; 9905 ierr = PetscStrcpy(multname,"MatMatMatMult_");CHKERRQ(ierr); 9906 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9907 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 9908 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 9909 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 9910 ierr = PetscStrcat(multname,((PetscObject)C)->type_name);CHKERRQ(ierr); 9911 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); 9912 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9913 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); 9914 } 9915 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9916 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9917 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9918 PetscFunctionReturn(0); 9919 } 9920 9921 #undef __FUNCT__ 9922 #define __FUNCT__ "MatCreateRedundantMatrix" 9923 /*@C 9924 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9925 9926 Collective on Mat 9927 9928 Input Parameters: 9929 + mat - the matrix 9930 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9931 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 9932 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9933 9934 Output Parameter: 9935 . matredundant - redundant matrix 9936 9937 Notes: 9938 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9939 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9940 9941 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 9942 calling it. 9943 9944 Level: advanced 9945 9946 Concepts: subcommunicator 9947 Concepts: duplicate matrix 9948 9949 .seealso: MatDestroy() 9950 @*/ 9951 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 9952 { 9953 PetscErrorCode ierr; 9954 MPI_Comm comm; 9955 PetscMPIInt size; 9956 PetscInt mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 9957 Mat_Redundant *redund=NULL; 9958 PetscSubcomm psubcomm=NULL; 9959 MPI_Comm subcomm_in=subcomm; 9960 Mat *matseq; 9961 IS isrow,iscol; 9962 PetscBool newsubcomm=PETSC_FALSE; 9963 9964 PetscFunctionBegin; 9965 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 9966 if (size == 1 || nsubcomm == 1) { 9967 if (reuse == MAT_INITIAL_MATRIX) { 9968 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 9969 } else { 9970 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 9971 } 9972 PetscFunctionReturn(0); 9973 } 9974 9975 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 9976 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 9977 PetscValidPointer(*matredundant,5); 9978 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 9979 } 9980 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9981 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9982 MatCheckPreallocated(mat,1); 9983 9984 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 9985 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 9986 /* create psubcomm, then get subcomm */ 9987 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 9988 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 9989 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 9990 9991 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 9992 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 9993 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 9994 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 9995 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 9996 newsubcomm = PETSC_TRUE; 9997 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 9998 } 9999 10000 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10001 if (reuse == MAT_INITIAL_MATRIX) { 10002 mloc_sub = PETSC_DECIDE; 10003 if (bs < 1) { 10004 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10005 } else { 10006 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10007 } 10008 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10009 rstart = rend - mloc_sub; 10010 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10011 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10012 } else { /* reuse == MAT_REUSE_MATRIX */ 10013 /* retrieve subcomm */ 10014 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10015 redund = (*matredundant)->redundant; 10016 isrow = redund->isrow; 10017 iscol = redund->iscol; 10018 matseq = redund->matseq; 10019 } 10020 ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10021 10022 /* get matredundant over subcomm */ 10023 if (reuse == MAT_INITIAL_MATRIX) { 10024 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);CHKERRQ(ierr); 10025 10026 /* create a supporting struct and attach it to C for reuse */ 10027 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10028 (*matredundant)->redundant = redund; 10029 redund->isrow = isrow; 10030 redund->iscol = iscol; 10031 redund->matseq = matseq; 10032 if (newsubcomm) { 10033 redund->subcomm = subcomm; 10034 } else { 10035 redund->subcomm = MPI_COMM_NULL; 10036 } 10037 } else { 10038 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10039 } 10040 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10041 PetscFunctionReturn(0); 10042 } 10043 10044 #undef __FUNCT__ 10045 #define __FUNCT__ "MatGetMultiProcBlock" 10046 /*@C 10047 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10048 a given 'mat' object. Each submatrix can span multiple procs. 10049 10050 Collective on Mat 10051 10052 Input Parameters: 10053 + mat - the matrix 10054 . subcomm - the subcommunicator obtained by com_split(comm) 10055 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10056 10057 Output Parameter: 10058 . subMat - 'parallel submatrices each spans a given subcomm 10059 10060 Notes: 10061 The submatrix partition across processors is dictated by 'subComm' a 10062 communicator obtained by com_split(comm). The comm_split 10063 is not restriced to be grouped with consecutive original ranks. 10064 10065 Due the comm_split() usage, the parallel layout of the submatrices 10066 map directly to the layout of the original matrix [wrt the local 10067 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10068 into the 'DiagonalMat' of the subMat, hence it is used directly from 10069 the subMat. However the offDiagMat looses some columns - and this is 10070 reconstructed with MatSetValues() 10071 10072 Level: advanced 10073 10074 Concepts: subcommunicator 10075 Concepts: submatrices 10076 10077 .seealso: MatGetSubMatrices() 10078 @*/ 10079 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10080 { 10081 PetscErrorCode ierr; 10082 PetscMPIInt commsize,subCommSize; 10083 10084 PetscFunctionBegin; 10085 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10086 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10087 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10088 10089 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10090 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10091 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10092 PetscFunctionReturn(0); 10093 } 10094 10095 #undef __FUNCT__ 10096 #define __FUNCT__ "MatGetLocalSubMatrix" 10097 /*@ 10098 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10099 10100 Not Collective 10101 10102 Input Arguments: 10103 mat - matrix to extract local submatrix from 10104 isrow - local row indices for submatrix 10105 iscol - local column indices for submatrix 10106 10107 Output Arguments: 10108 submat - the submatrix 10109 10110 Level: intermediate 10111 10112 Notes: 10113 The submat should be returned with MatRestoreLocalSubMatrix(). 10114 10115 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10116 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10117 10118 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10119 MatSetValuesBlockedLocal() will also be implemented. 10120 10121 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10122 matrices obtained with DMCreateMat() generally already have the local to global mapping provided. 10123 10124 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10125 @*/ 10126 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10127 { 10128 PetscErrorCode ierr; 10129 10130 PetscFunctionBegin; 10131 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10132 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10133 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10134 PetscCheckSameComm(isrow,2,iscol,3); 10135 PetscValidPointer(submat,4); 10136 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10137 10138 if (mat->ops->getlocalsubmatrix) { 10139 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10140 } else { 10141 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10142 } 10143 PetscFunctionReturn(0); 10144 } 10145 10146 #undef __FUNCT__ 10147 #define __FUNCT__ "MatRestoreLocalSubMatrix" 10148 /*@ 10149 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10150 10151 Not Collective 10152 10153 Input Arguments: 10154 mat - matrix to extract local submatrix from 10155 isrow - local row indices for submatrix 10156 iscol - local column indices for submatrix 10157 submat - the submatrix 10158 10159 Level: intermediate 10160 10161 .seealso: MatGetLocalSubMatrix() 10162 @*/ 10163 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10164 { 10165 PetscErrorCode ierr; 10166 10167 PetscFunctionBegin; 10168 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10169 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10170 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10171 PetscCheckSameComm(isrow,2,iscol,3); 10172 PetscValidPointer(submat,4); 10173 if (*submat) { 10174 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10175 } 10176 10177 if (mat->ops->restorelocalsubmatrix) { 10178 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10179 } else { 10180 ierr = MatDestroy(submat);CHKERRQ(ierr); 10181 } 10182 *submat = NULL; 10183 PetscFunctionReturn(0); 10184 } 10185 10186 /* --------------------------------------------------------*/ 10187 #undef __FUNCT__ 10188 #define __FUNCT__ "MatFindZeroDiagonals" 10189 /*@ 10190 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix 10191 10192 Collective on Mat 10193 10194 Input Parameter: 10195 . mat - the matrix 10196 10197 Output Parameter: 10198 . is - if any rows have zero diagonals this contains the list of them 10199 10200 Level: developer 10201 10202 Concepts: matrix-vector product 10203 10204 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10205 @*/ 10206 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10207 { 10208 PetscErrorCode ierr; 10209 10210 PetscFunctionBegin; 10211 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10212 PetscValidType(mat,1); 10213 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10214 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10215 10216 if (!mat->ops->findzerodiagonals) { 10217 Vec diag; 10218 const PetscScalar *a; 10219 PetscInt *rows; 10220 PetscInt rStart, rEnd, r, nrow = 0; 10221 10222 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10223 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10224 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10225 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10226 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10227 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10228 nrow = 0; 10229 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10230 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10231 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10232 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10233 } else { 10234 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10235 } 10236 PetscFunctionReturn(0); 10237 } 10238 10239 #undef __FUNCT__ 10240 #define __FUNCT__ "MatFindOffBlockDiagonalEntries" 10241 /*@ 10242 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10243 10244 Collective on Mat 10245 10246 Input Parameter: 10247 . mat - the matrix 10248 10249 Output Parameter: 10250 . is - contains the list of rows with off block diagonal entries 10251 10252 Level: developer 10253 10254 Concepts: matrix-vector product 10255 10256 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10257 @*/ 10258 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10259 { 10260 PetscErrorCode ierr; 10261 10262 PetscFunctionBegin; 10263 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10264 PetscValidType(mat,1); 10265 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10266 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10267 10268 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10269 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10270 PetscFunctionReturn(0); 10271 } 10272 10273 #undef __FUNCT__ 10274 #define __FUNCT__ "MatInvertBlockDiagonal" 10275 /*@C 10276 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10277 10278 Collective on Mat 10279 10280 Input Parameters: 10281 . mat - the matrix 10282 10283 Output Parameters: 10284 . values - the block inverses in column major order (FORTRAN-like) 10285 10286 Note: 10287 This routine is not available from Fortran. 10288 10289 Level: advanced 10290 @*/ 10291 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10292 { 10293 PetscErrorCode ierr; 10294 10295 PetscFunctionBegin; 10296 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10297 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10298 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10299 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10300 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10301 PetscFunctionReturn(0); 10302 } 10303 10304 #undef __FUNCT__ 10305 #define __FUNCT__ "MatTransposeColoringDestroy" 10306 /*@C 10307 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10308 via MatTransposeColoringCreate(). 10309 10310 Collective on MatTransposeColoring 10311 10312 Input Parameter: 10313 . c - coloring context 10314 10315 Level: intermediate 10316 10317 .seealso: MatTransposeColoringCreate() 10318 @*/ 10319 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10320 { 10321 PetscErrorCode ierr; 10322 MatTransposeColoring matcolor=*c; 10323 10324 PetscFunctionBegin; 10325 if (!matcolor) PetscFunctionReturn(0); 10326 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10327 10328 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10329 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10330 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10331 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10332 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10333 if (matcolor->brows>0) { 10334 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10335 } 10336 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10337 PetscFunctionReturn(0); 10338 } 10339 10340 #undef __FUNCT__ 10341 #define __FUNCT__ "MatTransColoringApplySpToDen" 10342 /*@C 10343 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10344 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10345 MatTransposeColoring to sparse B. 10346 10347 Collective on MatTransposeColoring 10348 10349 Input Parameters: 10350 + B - sparse matrix B 10351 . Btdense - symbolic dense matrix B^T 10352 - coloring - coloring context created with MatTransposeColoringCreate() 10353 10354 Output Parameter: 10355 . Btdense - dense matrix B^T 10356 10357 Options Database Keys: 10358 + -mat_transpose_coloring_view - Activates basic viewing or coloring 10359 . -mat_transpose_coloring_view_draw - Activates drawing of coloring 10360 - -mat_transpose_coloring_view_info - Activates viewing of coloring info 10361 10362 Level: intermediate 10363 10364 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy() 10365 10366 .keywords: coloring 10367 @*/ 10368 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10369 { 10370 PetscErrorCode ierr; 10371 10372 PetscFunctionBegin; 10373 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10374 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10375 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10376 10377 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10378 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10379 PetscFunctionReturn(0); 10380 } 10381 10382 #undef __FUNCT__ 10383 #define __FUNCT__ "MatTransColoringApplyDenToSp" 10384 /*@C 10385 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10386 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10387 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10388 Csp from Cden. 10389 10390 Collective on MatTransposeColoring 10391 10392 Input Parameters: 10393 + coloring - coloring context created with MatTransposeColoringCreate() 10394 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10395 10396 Output Parameter: 10397 . Csp - sparse matrix 10398 10399 Options Database Keys: 10400 + -mat_multtranspose_coloring_view - Activates basic viewing or coloring 10401 . -mat_multtranspose_coloring_view_draw - Activates drawing of coloring 10402 - -mat_multtranspose_coloring_view_info - Activates viewing of coloring info 10403 10404 Level: intermediate 10405 10406 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10407 10408 .keywords: coloring 10409 @*/ 10410 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10411 { 10412 PetscErrorCode ierr; 10413 10414 PetscFunctionBegin; 10415 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10416 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10417 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10418 10419 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10420 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10421 PetscFunctionReturn(0); 10422 } 10423 10424 #undef __FUNCT__ 10425 #define __FUNCT__ "MatTransposeColoringCreate" 10426 /*@C 10427 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10428 10429 Collective on Mat 10430 10431 Input Parameters: 10432 + mat - the matrix product C 10433 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10434 10435 Output Parameter: 10436 . color - the new coloring context 10437 10438 Level: intermediate 10439 10440 .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(), 10441 MatTransColoringApplyDenToSp(), MatTransposeColoringView(), 10442 @*/ 10443 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10444 { 10445 MatTransposeColoring c; 10446 MPI_Comm comm; 10447 PetscErrorCode ierr; 10448 10449 PetscFunctionBegin; 10450 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10451 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10452 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10453 10454 c->ctype = iscoloring->ctype; 10455 if (mat->ops->transposecoloringcreate) { 10456 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10457 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10458 10459 *color = c; 10460 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10461 PetscFunctionReturn(0); 10462 } 10463 10464 #undef __FUNCT__ 10465 #define __FUNCT__ "MatGetNonzeroState" 10466 /*@ 10467 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10468 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10469 same, otherwise it will be larger 10470 10471 Not Collective 10472 10473 Input Parameter: 10474 . A - the matrix 10475 10476 Output Parameter: 10477 . state - the current state 10478 10479 Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10480 different matrices 10481 10482 Level: intermediate 10483 10484 @*/ 10485 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10486 { 10487 PetscFunctionBegin; 10488 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10489 *state = mat->nonzerostate; 10490 PetscFunctionReturn(0); 10491 } 10492 10493 #undef __FUNCT__ 10494 #define __FUNCT__ "MatCreateMPIMatConcatenateSeqMat" 10495 /*@ 10496 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10497 matrices from each processor 10498 10499 Collective on MPI_Comm 10500 10501 Input Parameters: 10502 + comm - the communicators the parallel matrix will live on 10503 . seqmat - the input sequential matrices 10504 . n - number of local columns (or PETSC_DECIDE) 10505 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10506 10507 Output Parameter: 10508 . mpimat - the parallel matrix generated 10509 10510 Level: advanced 10511 10512 Notes: The number of columns of the matrix in EACH processor MUST be the same. 10513 10514 @*/ 10515 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10516 { 10517 PetscErrorCode ierr; 10518 PetscMPIInt size; 10519 10520 PetscFunctionBegin; 10521 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10522 if (size == 1) { 10523 if (reuse == MAT_INITIAL_MATRIX) { 10524 ierr = MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat);CHKERRQ(ierr); 10525 } else { 10526 ierr = MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10527 } 10528 PetscFunctionReturn(0); 10529 } 10530 10531 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10532 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10533 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10534 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10535 PetscFunctionReturn(0); 10536 } 10537 10538 #undef __FUNCT__ 10539 #define __FUNCT__ "MatSubdomainsCreateCoalesce" 10540 /*@ 10541 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10542 ranks' ownership ranges. 10543 10544 Collective on A 10545 10546 Input Parameters: 10547 + A - the matrix to create subdomains from 10548 - N - requested number of subdomains 10549 10550 10551 Output Parameters: 10552 + n - number of subdomains resulting on this rank 10553 - iss - IS list with indices of subdomains on this rank 10554 10555 Level: advanced 10556 10557 Notes: number of subdomains must be smaller than the communicator size 10558 @*/ 10559 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10560 { 10561 MPI_Comm comm,subcomm; 10562 PetscMPIInt size,rank,color; 10563 PetscInt rstart,rend,k; 10564 PetscErrorCode ierr; 10565 10566 PetscFunctionBegin; 10567 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10568 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10569 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10570 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); 10571 *n = 1; 10572 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10573 color = rank/k; 10574 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10575 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10576 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10577 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10578 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10579 PetscFunctionReturn(0); 10580 } 10581