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