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