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