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