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 PetscErrorCode ierr; 7201 7202 PetscFunctionBegin; 7203 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7204 PetscValidLogicalCollectiveInt(mat,bs,2); 7205 ierr = PetscLayoutSetBlockSize(mat->rmap,bs);CHKERRQ(ierr); 7206 ierr = PetscLayoutSetBlockSize(mat->cmap,bs);CHKERRQ(ierr); 7207 PetscFunctionReturn(0); 7208 } 7209 7210 #undef __FUNCT__ 7211 #define __FUNCT__ "MatSetBlockSizes" 7212 /*@ 7213 MatSetBlockSizes - Sets the matrix block row and column sizes. 7214 7215 Logically Collective on Mat 7216 7217 Input Parameters: 7218 + mat - the matrix 7219 - rbs - row block size 7220 - cbs - column block size 7221 7222 Notes: 7223 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7224 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7225 7226 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 7227 7228 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7229 7230 Level: intermediate 7231 7232 Concepts: matrices^block size 7233 7234 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7235 @*/ 7236 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7237 { 7238 PetscErrorCode ierr; 7239 7240 PetscFunctionBegin; 7241 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7242 PetscValidLogicalCollectiveInt(mat,rbs,2); 7243 PetscValidLogicalCollectiveInt(mat,cbs,3); 7244 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7245 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7246 PetscFunctionReturn(0); 7247 } 7248 7249 #undef __FUNCT__ 7250 #define __FUNCT__ "MatSetBlockSizesFromMats" 7251 /*@ 7252 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7253 7254 Logically Collective on Mat 7255 7256 Input Parameters: 7257 + mat - the matrix 7258 . fromRow - matrix from which to copy row block size 7259 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7260 7261 Level: developer 7262 7263 Concepts: matrices^block size 7264 7265 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7266 @*/ 7267 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7268 { 7269 PetscErrorCode ierr; 7270 7271 PetscFunctionBegin; 7272 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7273 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7274 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7275 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7276 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7277 PetscFunctionReturn(0); 7278 } 7279 7280 #undef __FUNCT__ 7281 #define __FUNCT__ "MatResidual" 7282 /*@ 7283 MatResidual - Default routine to calculate the residual. 7284 7285 Collective on Mat and Vec 7286 7287 Input Parameters: 7288 + mat - the matrix 7289 . b - the right-hand-side 7290 - x - the approximate solution 7291 7292 Output Parameter: 7293 . r - location to store the residual 7294 7295 Level: developer 7296 7297 .keywords: MG, default, multigrid, residual 7298 7299 .seealso: PCMGSetResidual() 7300 @*/ 7301 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7302 { 7303 PetscErrorCode ierr; 7304 7305 PetscFunctionBegin; 7306 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7307 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7308 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7309 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7310 PetscValidType(mat,1); 7311 MatCheckPreallocated(mat,1); 7312 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7313 if (!mat->ops->residual) { 7314 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7315 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7316 } else { 7317 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7318 } 7319 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7320 PetscFunctionReturn(0); 7321 } 7322 7323 #undef __FUNCT__ 7324 #define __FUNCT__ "MatGetRowIJ" 7325 /*@C 7326 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7327 7328 Collective on Mat 7329 7330 Input Parameters: 7331 + mat - the matrix 7332 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7333 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7334 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7335 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7336 always used. 7337 7338 Output Parameters: 7339 + n - number of rows in the (possibly compressed) matrix 7340 . ia - the row pointers [of length n+1] 7341 . ja - the column indices 7342 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7343 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7344 7345 Level: developer 7346 7347 Notes: You CANNOT change any of the ia[] or ja[] values. 7348 7349 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values 7350 7351 Fortran Node 7352 7353 In Fortran use 7354 $ PetscInt ia(1), ja(1) 7355 $ PetscOffset iia, jja 7356 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7357 $ Acess the ith and jth entries via ia(iia + i) and ja(jja + j) 7358 $ 7359 $ or 7360 $ 7361 $ PetscInt, pointer :: ia(:),ja(:) 7362 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7363 $ Acess the ith and jth entries via ia(i) and ja(j) 7364 7365 7366 7367 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7368 @*/ 7369 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7370 { 7371 PetscErrorCode ierr; 7372 7373 PetscFunctionBegin; 7374 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7375 PetscValidType(mat,1); 7376 PetscValidIntPointer(n,4); 7377 if (ia) PetscValidIntPointer(ia,5); 7378 if (ja) PetscValidIntPointer(ja,6); 7379 PetscValidIntPointer(done,7); 7380 MatCheckPreallocated(mat,1); 7381 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7382 else { 7383 *done = PETSC_TRUE; 7384 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7385 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7386 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7387 } 7388 PetscFunctionReturn(0); 7389 } 7390 7391 #undef __FUNCT__ 7392 #define __FUNCT__ "MatGetColumnIJ" 7393 /*@C 7394 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7395 7396 Collective on Mat 7397 7398 Input Parameters: 7399 + mat - the matrix 7400 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7401 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7402 symmetrized 7403 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7404 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7405 always used. 7406 . n - number of columns in the (possibly compressed) matrix 7407 . ia - the column pointers 7408 - ja - the row indices 7409 7410 Output Parameters: 7411 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7412 7413 Note: 7414 This routine zeros out n, ia, and ja. This is to prevent accidental 7415 us of the array after it has been restored. If you pass NULL, it will 7416 not zero the pointers. Use of ia or ja after MatRestoreColumnIJ() is invalid. 7417 7418 Level: developer 7419 7420 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7421 @*/ 7422 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7423 { 7424 PetscErrorCode ierr; 7425 7426 PetscFunctionBegin; 7427 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7428 PetscValidType(mat,1); 7429 PetscValidIntPointer(n,4); 7430 if (ia) PetscValidIntPointer(ia,5); 7431 if (ja) PetscValidIntPointer(ja,6); 7432 PetscValidIntPointer(done,7); 7433 MatCheckPreallocated(mat,1); 7434 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7435 else { 7436 *done = PETSC_TRUE; 7437 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7438 } 7439 PetscFunctionReturn(0); 7440 } 7441 7442 #undef __FUNCT__ 7443 #define __FUNCT__ "MatRestoreRowIJ" 7444 /*@C 7445 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7446 MatGetRowIJ(). 7447 7448 Collective on Mat 7449 7450 Input Parameters: 7451 + mat - the matrix 7452 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7453 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7454 symmetrized 7455 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7456 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7457 always used. 7458 . n - size of (possibly compressed) matrix 7459 . ia - the row pointers 7460 - ja - the column indices 7461 7462 Output Parameters: 7463 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7464 7465 Note: 7466 This routine zeros out n, ia, and ja. This is to prevent accidental 7467 us of the array after it has been restored. If you pass NULL, it will 7468 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7469 7470 Level: developer 7471 7472 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7473 @*/ 7474 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7475 { 7476 PetscErrorCode ierr; 7477 7478 PetscFunctionBegin; 7479 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7480 PetscValidType(mat,1); 7481 if (ia) PetscValidIntPointer(ia,5); 7482 if (ja) PetscValidIntPointer(ja,6); 7483 PetscValidIntPointer(done,7); 7484 MatCheckPreallocated(mat,1); 7485 7486 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7487 else { 7488 *done = PETSC_TRUE; 7489 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7490 if (n) *n = 0; 7491 if (ia) *ia = NULL; 7492 if (ja) *ja = NULL; 7493 } 7494 PetscFunctionReturn(0); 7495 } 7496 7497 #undef __FUNCT__ 7498 #define __FUNCT__ "MatRestoreColumnIJ" 7499 /*@C 7500 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7501 MatGetColumnIJ(). 7502 7503 Collective on Mat 7504 7505 Input Parameters: 7506 + mat - the matrix 7507 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7508 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7509 symmetrized 7510 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7511 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7512 always used. 7513 7514 Output Parameters: 7515 + n - size of (possibly compressed) matrix 7516 . ia - the column pointers 7517 . ja - the row indices 7518 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7519 7520 Level: developer 7521 7522 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7523 @*/ 7524 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7525 { 7526 PetscErrorCode ierr; 7527 7528 PetscFunctionBegin; 7529 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7530 PetscValidType(mat,1); 7531 if (ia) PetscValidIntPointer(ia,5); 7532 if (ja) PetscValidIntPointer(ja,6); 7533 PetscValidIntPointer(done,7); 7534 MatCheckPreallocated(mat,1); 7535 7536 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7537 else { 7538 *done = PETSC_TRUE; 7539 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7540 if (n) *n = 0; 7541 if (ia) *ia = NULL; 7542 if (ja) *ja = NULL; 7543 } 7544 PetscFunctionReturn(0); 7545 } 7546 7547 #undef __FUNCT__ 7548 #define __FUNCT__ "MatColoringPatch" 7549 /*@C 7550 MatColoringPatch -Used inside matrix coloring routines that 7551 use MatGetRowIJ() and/or MatGetColumnIJ(). 7552 7553 Collective on Mat 7554 7555 Input Parameters: 7556 + mat - the matrix 7557 . ncolors - max color value 7558 . n - number of entries in colorarray 7559 - colorarray - array indicating color for each column 7560 7561 Output Parameters: 7562 . iscoloring - coloring generated using colorarray information 7563 7564 Level: developer 7565 7566 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7567 7568 @*/ 7569 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7570 { 7571 PetscErrorCode ierr; 7572 7573 PetscFunctionBegin; 7574 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7575 PetscValidType(mat,1); 7576 PetscValidIntPointer(colorarray,4); 7577 PetscValidPointer(iscoloring,5); 7578 MatCheckPreallocated(mat,1); 7579 7580 if (!mat->ops->coloringpatch) { 7581 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7582 } else { 7583 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7584 } 7585 PetscFunctionReturn(0); 7586 } 7587 7588 7589 #undef __FUNCT__ 7590 #define __FUNCT__ "MatSetUnfactored" 7591 /*@ 7592 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7593 7594 Logically Collective on Mat 7595 7596 Input Parameter: 7597 . mat - the factored matrix to be reset 7598 7599 Notes: 7600 This routine should be used only with factored matrices formed by in-place 7601 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7602 format). This option can save memory, for example, when solving nonlinear 7603 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7604 ILU(0) preconditioner. 7605 7606 Note that one can specify in-place ILU(0) factorization by calling 7607 .vb 7608 PCType(pc,PCILU); 7609 PCFactorSeUseInPlace(pc); 7610 .ve 7611 or by using the options -pc_type ilu -pc_factor_in_place 7612 7613 In-place factorization ILU(0) can also be used as a local 7614 solver for the blocks within the block Jacobi or additive Schwarz 7615 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7616 for details on setting local solver options. 7617 7618 Most users should employ the simplified KSP interface for linear solvers 7619 instead of working directly with matrix algebra routines such as this. 7620 See, e.g., KSPCreate(). 7621 7622 Level: developer 7623 7624 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7625 7626 Concepts: matrices^unfactored 7627 7628 @*/ 7629 PetscErrorCode MatSetUnfactored(Mat mat) 7630 { 7631 PetscErrorCode ierr; 7632 7633 PetscFunctionBegin; 7634 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7635 PetscValidType(mat,1); 7636 MatCheckPreallocated(mat,1); 7637 mat->factortype = MAT_FACTOR_NONE; 7638 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7639 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7640 PetscFunctionReturn(0); 7641 } 7642 7643 /*MC 7644 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7645 7646 Synopsis: 7647 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7648 7649 Not collective 7650 7651 Input Parameter: 7652 . x - matrix 7653 7654 Output Parameters: 7655 + xx_v - the Fortran90 pointer to the array 7656 - ierr - error code 7657 7658 Example of Usage: 7659 .vb 7660 PetscScalar, pointer xx_v(:,:) 7661 .... 7662 call MatDenseGetArrayF90(x,xx_v,ierr) 7663 a = xx_v(3) 7664 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7665 .ve 7666 7667 Level: advanced 7668 7669 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7670 7671 Concepts: matrices^accessing array 7672 7673 M*/ 7674 7675 /*MC 7676 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7677 accessed with MatDenseGetArrayF90(). 7678 7679 Synopsis: 7680 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7681 7682 Not collective 7683 7684 Input Parameters: 7685 + x - matrix 7686 - xx_v - the Fortran90 pointer to the array 7687 7688 Output Parameter: 7689 . ierr - error code 7690 7691 Example of Usage: 7692 .vb 7693 PetscScalar, pointer xx_v(:,:) 7694 .... 7695 call MatDenseGetArrayF90(x,xx_v,ierr) 7696 a = xx_v(3) 7697 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7698 .ve 7699 7700 Level: advanced 7701 7702 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7703 7704 M*/ 7705 7706 7707 /*MC 7708 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7709 7710 Synopsis: 7711 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7712 7713 Not collective 7714 7715 Input Parameter: 7716 . x - matrix 7717 7718 Output Parameters: 7719 + xx_v - the Fortran90 pointer to the array 7720 - ierr - error code 7721 7722 Example of Usage: 7723 .vb 7724 PetscScalar, pointer xx_v(:) 7725 .... 7726 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7727 a = xx_v(3) 7728 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7729 .ve 7730 7731 Level: advanced 7732 7733 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7734 7735 Concepts: matrices^accessing array 7736 7737 M*/ 7738 7739 /*MC 7740 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7741 accessed with MatSeqAIJGetArrayF90(). 7742 7743 Synopsis: 7744 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7745 7746 Not collective 7747 7748 Input Parameters: 7749 + x - matrix 7750 - xx_v - the Fortran90 pointer to the array 7751 7752 Output Parameter: 7753 . ierr - error code 7754 7755 Example of Usage: 7756 .vb 7757 PetscScalar, pointer xx_v(:) 7758 .... 7759 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7760 a = xx_v(3) 7761 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7762 .ve 7763 7764 Level: advanced 7765 7766 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7767 7768 M*/ 7769 7770 7771 #undef __FUNCT__ 7772 #define __FUNCT__ "MatGetSubMatrix" 7773 /*@ 7774 MatGetSubMatrix - Gets a single submatrix on the same number of processors 7775 as the original matrix. 7776 7777 Collective on Mat 7778 7779 Input Parameters: 7780 + mat - the original matrix 7781 . isrow - parallel IS containing the rows this processor should obtain 7782 . 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. 7783 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7784 7785 Output Parameter: 7786 . newmat - the new submatrix, of the same type as the old 7787 7788 Level: advanced 7789 7790 Notes: 7791 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7792 7793 Some matrix types place restrictions on the row and column indices, such 7794 as that they be sorted or that they be equal to each other. 7795 7796 The index sets may not have duplicate entries. 7797 7798 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7799 the MatGetSubMatrix() routine will create the newmat for you. Any additional calls 7800 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7801 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7802 you are finished using it. 7803 7804 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7805 the input matrix. 7806 7807 If iscol is NULL then all columns are obtained (not supported in Fortran). 7808 7809 Example usage: 7810 Consider the following 8x8 matrix with 34 non-zero values, that is 7811 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7812 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7813 as follows: 7814 7815 .vb 7816 1 2 0 | 0 3 0 | 0 4 7817 Proc0 0 5 6 | 7 0 0 | 8 0 7818 9 0 10 | 11 0 0 | 12 0 7819 ------------------------------------- 7820 13 0 14 | 15 16 17 | 0 0 7821 Proc1 0 18 0 | 19 20 21 | 0 0 7822 0 0 0 | 22 23 0 | 24 0 7823 ------------------------------------- 7824 Proc2 25 26 27 | 0 0 28 | 29 0 7825 30 0 0 | 31 32 33 | 0 34 7826 .ve 7827 7828 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7829 7830 .vb 7831 2 0 | 0 3 0 | 0 7832 Proc0 5 6 | 7 0 0 | 8 7833 ------------------------------- 7834 Proc1 18 0 | 19 20 21 | 0 7835 ------------------------------- 7836 Proc2 26 27 | 0 0 28 | 29 7837 0 0 | 31 32 33 | 0 7838 .ve 7839 7840 7841 Concepts: matrices^submatrices 7842 7843 .seealso: MatGetSubMatrices() 7844 @*/ 7845 PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7846 { 7847 PetscErrorCode ierr; 7848 PetscMPIInt size; 7849 Mat *local; 7850 IS iscoltmp; 7851 7852 PetscFunctionBegin; 7853 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7854 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7855 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7856 PetscValidPointer(newmat,5); 7857 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7858 PetscValidType(mat,1); 7859 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7860 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 7861 7862 MatCheckPreallocated(mat,1); 7863 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 7864 7865 if (!iscol || isrow == iscol) { 7866 PetscBool stride; 7867 PetscMPIInt grabentirematrix = 0,grab; 7868 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 7869 if (stride) { 7870 PetscInt first,step,n,rstart,rend; 7871 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 7872 if (step == 1) { 7873 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 7874 if (rstart == first) { 7875 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 7876 if (n == rend-rstart) { 7877 grabentirematrix = 1; 7878 } 7879 } 7880 } 7881 } 7882 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 7883 if (grab) { 7884 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 7885 if (cll == MAT_INITIAL_MATRIX) { 7886 *newmat = mat; 7887 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 7888 } 7889 PetscFunctionReturn(0); 7890 } 7891 } 7892 7893 if (!iscol) { 7894 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 7895 } else { 7896 iscoltmp = iscol; 7897 } 7898 7899 /* if original matrix is on just one processor then use submatrix generated */ 7900 if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 7901 ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 7902 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7903 PetscFunctionReturn(0); 7904 } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) { 7905 ierr = MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 7906 *newmat = *local; 7907 ierr = PetscFree(local);CHKERRQ(ierr); 7908 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7909 PetscFunctionReturn(0); 7910 } else if (!mat->ops->getsubmatrix) { 7911 /* Create a new matrix type that implements the operation using the full matrix */ 7912 ierr = PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr); 7913 switch (cll) { 7914 case MAT_INITIAL_MATRIX: 7915 ierr = MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 7916 break; 7917 case MAT_REUSE_MATRIX: 7918 ierr = MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 7919 break; 7920 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 7921 } 7922 ierr = PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr); 7923 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7924 PetscFunctionReturn(0); 7925 } 7926 7927 if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7928 ierr = PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr); 7929 ierr = (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 7930 ierr = PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);CHKERRQ(ierr); 7931 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7932 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 7933 PetscFunctionReturn(0); 7934 } 7935 7936 #undef __FUNCT__ 7937 #define __FUNCT__ "MatStashSetInitialSize" 7938 /*@ 7939 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 7940 used during the assembly process to store values that belong to 7941 other processors. 7942 7943 Not Collective 7944 7945 Input Parameters: 7946 + mat - the matrix 7947 . size - the initial size of the stash. 7948 - bsize - the initial size of the block-stash(if used). 7949 7950 Options Database Keys: 7951 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 7952 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 7953 7954 Level: intermediate 7955 7956 Notes: 7957 The block-stash is used for values set with MatSetValuesBlocked() while 7958 the stash is used for values set with MatSetValues() 7959 7960 Run with the option -info and look for output of the form 7961 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 7962 to determine the appropriate value, MM, to use for size and 7963 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 7964 to determine the value, BMM to use for bsize 7965 7966 Concepts: stash^setting matrix size 7967 Concepts: matrices^stash 7968 7969 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 7970 7971 @*/ 7972 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 7973 { 7974 PetscErrorCode ierr; 7975 7976 PetscFunctionBegin; 7977 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7978 PetscValidType(mat,1); 7979 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 7980 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 7981 PetscFunctionReturn(0); 7982 } 7983 7984 #undef __FUNCT__ 7985 #define __FUNCT__ "MatInterpolateAdd" 7986 /*@ 7987 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 7988 the matrix 7989 7990 Neighbor-wise Collective on Mat 7991 7992 Input Parameters: 7993 + mat - the matrix 7994 . x,y - the vectors 7995 - w - where the result is stored 7996 7997 Level: intermediate 7998 7999 Notes: 8000 w may be the same vector as y. 8001 8002 This allows one to use either the restriction or interpolation (its transpose) 8003 matrix to do the interpolation 8004 8005 Concepts: interpolation 8006 8007 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8008 8009 @*/ 8010 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8011 { 8012 PetscErrorCode ierr; 8013 PetscInt M,N,Ny; 8014 8015 PetscFunctionBegin; 8016 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8017 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8018 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8019 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8020 PetscValidType(A,1); 8021 MatCheckPreallocated(A,1); 8022 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8023 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8024 if (M == Ny) { 8025 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 8026 } else { 8027 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 8028 } 8029 PetscFunctionReturn(0); 8030 } 8031 8032 #undef __FUNCT__ 8033 #define __FUNCT__ "MatInterpolate" 8034 /*@ 8035 MatInterpolate - y = A*x or A'*x depending on the shape of 8036 the matrix 8037 8038 Neighbor-wise Collective on Mat 8039 8040 Input Parameters: 8041 + mat - the matrix 8042 - x,y - the vectors 8043 8044 Level: intermediate 8045 8046 Notes: 8047 This allows one to use either the restriction or interpolation (its transpose) 8048 matrix to do the interpolation 8049 8050 Concepts: matrices^interpolation 8051 8052 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8053 8054 @*/ 8055 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8056 { 8057 PetscErrorCode ierr; 8058 PetscInt M,N,Ny; 8059 8060 PetscFunctionBegin; 8061 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8062 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8063 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8064 PetscValidType(A,1); 8065 MatCheckPreallocated(A,1); 8066 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8067 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8068 if (M == Ny) { 8069 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8070 } else { 8071 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8072 } 8073 PetscFunctionReturn(0); 8074 } 8075 8076 #undef __FUNCT__ 8077 #define __FUNCT__ "MatRestrict" 8078 /*@ 8079 MatRestrict - y = A*x or A'*x 8080 8081 Neighbor-wise Collective on Mat 8082 8083 Input Parameters: 8084 + mat - the matrix 8085 - x,y - the vectors 8086 8087 Level: intermediate 8088 8089 Notes: 8090 This allows one to use either the restriction or interpolation (its transpose) 8091 matrix to do the restriction 8092 8093 Concepts: matrices^restriction 8094 8095 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8096 8097 @*/ 8098 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8099 { 8100 PetscErrorCode ierr; 8101 PetscInt M,N,Ny; 8102 8103 PetscFunctionBegin; 8104 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8105 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8106 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8107 PetscValidType(A,1); 8108 MatCheckPreallocated(A,1); 8109 8110 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8111 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8112 if (M == Ny) { 8113 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8114 } else { 8115 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8116 } 8117 PetscFunctionReturn(0); 8118 } 8119 8120 #undef __FUNCT__ 8121 #define __FUNCT__ "MatGetNullSpace" 8122 /*@ 8123 MatGetNullSpace - retrieves the null space to a matrix. 8124 8125 Logically Collective on Mat and MatNullSpace 8126 8127 Input Parameters: 8128 + mat - the matrix 8129 - nullsp - the null space object 8130 8131 Level: developer 8132 8133 Concepts: null space^attaching to matrix 8134 8135 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8136 @*/ 8137 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8138 { 8139 PetscFunctionBegin; 8140 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8141 PetscValidType(mat,1); 8142 PetscValidPointer(nullsp,2); 8143 *nullsp = mat->nullsp; 8144 PetscFunctionReturn(0); 8145 } 8146 8147 #undef __FUNCT__ 8148 #define __FUNCT__ "MatSetNullSpace" 8149 /*@ 8150 MatSetNullSpace - attaches a null space to a matrix. 8151 8152 Logically Collective on Mat and MatNullSpace 8153 8154 Input Parameters: 8155 + mat - the matrix 8156 - nullsp - the null space object 8157 8158 Level: advanced 8159 8160 Notes: 8161 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8162 8163 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8164 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8165 8166 You can remove the null space by calling this routine with an nullsp of NULL 8167 8168 8169 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8170 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). 8171 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 8172 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 8173 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). 8174 8175 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8176 8177 Concepts: null space^attaching to matrix 8178 8179 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8180 @*/ 8181 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8182 { 8183 PetscErrorCode ierr; 8184 8185 PetscFunctionBegin; 8186 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8187 PetscValidType(mat,1); 8188 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8189 MatCheckPreallocated(mat,1); 8190 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8191 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8192 mat->nullsp = nullsp; 8193 PetscFunctionReturn(0); 8194 } 8195 8196 #undef __FUNCT__ 8197 #define __FUNCT__ "MatGetTransposeNullSpace" 8198 /*@ 8199 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8200 8201 Logically Collective on Mat and MatNullSpace 8202 8203 Input Parameters: 8204 + mat - the matrix 8205 - nullsp - the null space object 8206 8207 Level: developer 8208 8209 Concepts: null space^attaching to matrix 8210 8211 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8212 @*/ 8213 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8214 { 8215 PetscFunctionBegin; 8216 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8217 PetscValidType(mat,1); 8218 PetscValidPointer(nullsp,2); 8219 *nullsp = mat->transnullsp; 8220 PetscFunctionReturn(0); 8221 } 8222 8223 #undef __FUNCT__ 8224 #define __FUNCT__ "MatSetTransposeNullSpace" 8225 /*@ 8226 MatSetTransposeNullSpace - attaches a null space to a matrix. 8227 8228 Logically Collective on Mat and MatNullSpace 8229 8230 Input Parameters: 8231 + mat - the matrix 8232 - nullsp - the null space object 8233 8234 Level: advanced 8235 8236 Notes: 8237 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. 8238 You must also call MatSetNullSpace() 8239 8240 8241 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8242 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). 8243 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 8244 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 8245 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). 8246 8247 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8248 8249 Concepts: null space^attaching to matrix 8250 8251 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8252 @*/ 8253 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8254 { 8255 PetscErrorCode ierr; 8256 8257 PetscFunctionBegin; 8258 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8259 PetscValidType(mat,1); 8260 PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8261 MatCheckPreallocated(mat,1); 8262 ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr); 8263 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8264 mat->transnullsp = nullsp; 8265 PetscFunctionReturn(0); 8266 } 8267 8268 #undef __FUNCT__ 8269 #define __FUNCT__ "MatSetNearNullSpace" 8270 /*@ 8271 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8272 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8273 8274 Logically Collective on Mat and MatNullSpace 8275 8276 Input Parameters: 8277 + mat - the matrix 8278 - nullsp - the null space object 8279 8280 Level: advanced 8281 8282 Notes: 8283 Overwrites any previous near null space that may have been attached 8284 8285 You can remove the null space by calling this routine with an nullsp of NULL 8286 8287 Concepts: null space^attaching to matrix 8288 8289 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8290 @*/ 8291 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8292 { 8293 PetscErrorCode ierr; 8294 8295 PetscFunctionBegin; 8296 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8297 PetscValidType(mat,1); 8298 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8299 MatCheckPreallocated(mat,1); 8300 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8301 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8302 mat->nearnullsp = nullsp; 8303 PetscFunctionReturn(0); 8304 } 8305 8306 #undef __FUNCT__ 8307 #define __FUNCT__ "MatGetNearNullSpace" 8308 /*@ 8309 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8310 8311 Not Collective 8312 8313 Input Parameters: 8314 . mat - the matrix 8315 8316 Output Parameters: 8317 . nullsp - the null space object, NULL if not set 8318 8319 Level: developer 8320 8321 Concepts: null space^attaching to matrix 8322 8323 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8324 @*/ 8325 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8326 { 8327 PetscFunctionBegin; 8328 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8329 PetscValidType(mat,1); 8330 PetscValidPointer(nullsp,2); 8331 MatCheckPreallocated(mat,1); 8332 *nullsp = mat->nearnullsp; 8333 PetscFunctionReturn(0); 8334 } 8335 8336 #undef __FUNCT__ 8337 #define __FUNCT__ "MatICCFactor" 8338 /*@C 8339 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8340 8341 Collective on Mat 8342 8343 Input Parameters: 8344 + mat - the matrix 8345 . row - row/column permutation 8346 . fill - expected fill factor >= 1.0 8347 - level - level of fill, for ICC(k) 8348 8349 Notes: 8350 Probably really in-place only when level of fill is zero, otherwise allocates 8351 new space to store factored matrix and deletes previous memory. 8352 8353 Most users should employ the simplified KSP interface for linear solvers 8354 instead of working directly with matrix algebra routines such as this. 8355 See, e.g., KSPCreate(). 8356 8357 Level: developer 8358 8359 Concepts: matrices^incomplete Cholesky factorization 8360 Concepts: Cholesky factorization 8361 8362 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8363 8364 Developer Note: fortran interface is not autogenerated as the f90 8365 interface defintion cannot be generated correctly [due to MatFactorInfo] 8366 8367 @*/ 8368 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8369 { 8370 PetscErrorCode ierr; 8371 8372 PetscFunctionBegin; 8373 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8374 PetscValidType(mat,1); 8375 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8376 PetscValidPointer(info,3); 8377 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8378 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8379 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8380 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8381 MatCheckPreallocated(mat,1); 8382 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8383 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8384 PetscFunctionReturn(0); 8385 } 8386 8387 #undef __FUNCT__ 8388 #define __FUNCT__ "MatDiagonalScaleLocal" 8389 /*@ 8390 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8391 ghosted ones. 8392 8393 Not Collective 8394 8395 Input Parameters: 8396 + mat - the matrix 8397 - diag = the diagonal values, including ghost ones 8398 8399 Level: developer 8400 8401 Notes: Works only for MPIAIJ and MPIBAIJ matrices 8402 8403 .seealso: MatDiagonalScale() 8404 @*/ 8405 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8406 { 8407 PetscErrorCode ierr; 8408 PetscMPIInt size; 8409 8410 PetscFunctionBegin; 8411 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8412 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8413 PetscValidType(mat,1); 8414 8415 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8416 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8417 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8418 if (size == 1) { 8419 PetscInt n,m; 8420 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8421 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8422 if (m == n) { 8423 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8424 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8425 } else { 8426 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8427 } 8428 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8429 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8430 PetscFunctionReturn(0); 8431 } 8432 8433 #undef __FUNCT__ 8434 #define __FUNCT__ "MatGetInertia" 8435 /*@ 8436 MatGetInertia - Gets the inertia from a factored matrix 8437 8438 Collective on Mat 8439 8440 Input Parameter: 8441 . mat - the matrix 8442 8443 Output Parameters: 8444 + nneg - number of negative eigenvalues 8445 . nzero - number of zero eigenvalues 8446 - npos - number of positive eigenvalues 8447 8448 Level: advanced 8449 8450 Notes: Matrix must have been factored by MatCholeskyFactor() 8451 8452 8453 @*/ 8454 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8455 { 8456 PetscErrorCode ierr; 8457 8458 PetscFunctionBegin; 8459 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8460 PetscValidType(mat,1); 8461 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8462 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8463 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8464 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8465 PetscFunctionReturn(0); 8466 } 8467 8468 /* ----------------------------------------------------------------*/ 8469 #undef __FUNCT__ 8470 #define __FUNCT__ "MatSolves" 8471 /*@C 8472 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8473 8474 Neighbor-wise Collective on Mat and Vecs 8475 8476 Input Parameters: 8477 + mat - the factored matrix 8478 - b - the right-hand-side vectors 8479 8480 Output Parameter: 8481 . x - the result vectors 8482 8483 Notes: 8484 The vectors b and x cannot be the same. I.e., one cannot 8485 call MatSolves(A,x,x). 8486 8487 Notes: 8488 Most users should employ the simplified KSP interface for linear solvers 8489 instead of working directly with matrix algebra routines such as this. 8490 See, e.g., KSPCreate(). 8491 8492 Level: developer 8493 8494 Concepts: matrices^triangular solves 8495 8496 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8497 @*/ 8498 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8499 { 8500 PetscErrorCode ierr; 8501 8502 PetscFunctionBegin; 8503 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8504 PetscValidType(mat,1); 8505 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8506 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8507 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8508 8509 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8510 MatCheckPreallocated(mat,1); 8511 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8512 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8513 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8514 PetscFunctionReturn(0); 8515 } 8516 8517 #undef __FUNCT__ 8518 #define __FUNCT__ "MatIsSymmetric" 8519 /*@ 8520 MatIsSymmetric - Test whether a matrix is symmetric 8521 8522 Collective on Mat 8523 8524 Input Parameter: 8525 + A - the matrix to test 8526 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8527 8528 Output Parameters: 8529 . flg - the result 8530 8531 Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8532 8533 Level: intermediate 8534 8535 Concepts: matrix^symmetry 8536 8537 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8538 @*/ 8539 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8540 { 8541 PetscErrorCode ierr; 8542 8543 PetscFunctionBegin; 8544 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8545 PetscValidPointer(flg,2); 8546 8547 if (!A->symmetric_set) { 8548 if (!A->ops->issymmetric) { 8549 MatType mattype; 8550 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8551 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8552 } 8553 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8554 if (!tol) { 8555 A->symmetric_set = PETSC_TRUE; 8556 A->symmetric = *flg; 8557 if (A->symmetric) { 8558 A->structurally_symmetric_set = PETSC_TRUE; 8559 A->structurally_symmetric = PETSC_TRUE; 8560 } 8561 } 8562 } else if (A->symmetric) { 8563 *flg = PETSC_TRUE; 8564 } else if (!tol) { 8565 *flg = PETSC_FALSE; 8566 } else { 8567 if (!A->ops->issymmetric) { 8568 MatType mattype; 8569 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8570 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8571 } 8572 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8573 } 8574 PetscFunctionReturn(0); 8575 } 8576 8577 #undef __FUNCT__ 8578 #define __FUNCT__ "MatIsHermitian" 8579 /*@ 8580 MatIsHermitian - Test whether a matrix is Hermitian 8581 8582 Collective on Mat 8583 8584 Input Parameter: 8585 + A - the matrix to test 8586 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8587 8588 Output Parameters: 8589 . flg - the result 8590 8591 Level: intermediate 8592 8593 Concepts: matrix^symmetry 8594 8595 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8596 MatIsSymmetricKnown(), MatIsSymmetric() 8597 @*/ 8598 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8599 { 8600 PetscErrorCode ierr; 8601 8602 PetscFunctionBegin; 8603 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8604 PetscValidPointer(flg,2); 8605 8606 if (!A->hermitian_set) { 8607 if (!A->ops->ishermitian) { 8608 MatType mattype; 8609 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8610 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8611 } 8612 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8613 if (!tol) { 8614 A->hermitian_set = PETSC_TRUE; 8615 A->hermitian = *flg; 8616 if (A->hermitian) { 8617 A->structurally_symmetric_set = PETSC_TRUE; 8618 A->structurally_symmetric = PETSC_TRUE; 8619 } 8620 } 8621 } else if (A->hermitian) { 8622 *flg = PETSC_TRUE; 8623 } else if (!tol) { 8624 *flg = PETSC_FALSE; 8625 } else { 8626 if (!A->ops->ishermitian) { 8627 MatType mattype; 8628 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8629 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8630 } 8631 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8632 } 8633 PetscFunctionReturn(0); 8634 } 8635 8636 #undef __FUNCT__ 8637 #define __FUNCT__ "MatIsSymmetricKnown" 8638 /*@ 8639 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8640 8641 Not Collective 8642 8643 Input Parameter: 8644 . A - the matrix to check 8645 8646 Output Parameters: 8647 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8648 - flg - the result 8649 8650 Level: advanced 8651 8652 Concepts: matrix^symmetry 8653 8654 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8655 if you want it explicitly checked 8656 8657 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8658 @*/ 8659 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8660 { 8661 PetscFunctionBegin; 8662 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8663 PetscValidPointer(set,2); 8664 PetscValidPointer(flg,3); 8665 if (A->symmetric_set) { 8666 *set = PETSC_TRUE; 8667 *flg = A->symmetric; 8668 } else { 8669 *set = PETSC_FALSE; 8670 } 8671 PetscFunctionReturn(0); 8672 } 8673 8674 #undef __FUNCT__ 8675 #define __FUNCT__ "MatIsHermitianKnown" 8676 /*@ 8677 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8678 8679 Not Collective 8680 8681 Input Parameter: 8682 . A - the matrix to check 8683 8684 Output Parameters: 8685 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8686 - flg - the result 8687 8688 Level: advanced 8689 8690 Concepts: matrix^symmetry 8691 8692 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8693 if you want it explicitly checked 8694 8695 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8696 @*/ 8697 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8698 { 8699 PetscFunctionBegin; 8700 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8701 PetscValidPointer(set,2); 8702 PetscValidPointer(flg,3); 8703 if (A->hermitian_set) { 8704 *set = PETSC_TRUE; 8705 *flg = A->hermitian; 8706 } else { 8707 *set = PETSC_FALSE; 8708 } 8709 PetscFunctionReturn(0); 8710 } 8711 8712 #undef __FUNCT__ 8713 #define __FUNCT__ "MatIsStructurallySymmetric" 8714 /*@ 8715 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8716 8717 Collective on Mat 8718 8719 Input Parameter: 8720 . A - the matrix to test 8721 8722 Output Parameters: 8723 . flg - the result 8724 8725 Level: intermediate 8726 8727 Concepts: matrix^symmetry 8728 8729 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8730 @*/ 8731 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8732 { 8733 PetscErrorCode ierr; 8734 8735 PetscFunctionBegin; 8736 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8737 PetscValidPointer(flg,2); 8738 if (!A->structurally_symmetric_set) { 8739 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8740 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8741 8742 A->structurally_symmetric_set = PETSC_TRUE; 8743 } 8744 *flg = A->structurally_symmetric; 8745 PetscFunctionReturn(0); 8746 } 8747 8748 #undef __FUNCT__ 8749 #define __FUNCT__ "MatStashGetInfo" 8750 extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*); 8751 /*@ 8752 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8753 to be communicated to other processors during the MatAssemblyBegin/End() process 8754 8755 Not collective 8756 8757 Input Parameter: 8758 . vec - the vector 8759 8760 Output Parameters: 8761 + nstash - the size of the stash 8762 . reallocs - the number of additional mallocs incurred. 8763 . bnstash - the size of the block stash 8764 - breallocs - the number of additional mallocs incurred.in the block stash 8765 8766 Level: advanced 8767 8768 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8769 8770 @*/ 8771 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8772 { 8773 PetscErrorCode ierr; 8774 8775 PetscFunctionBegin; 8776 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8777 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8778 PetscFunctionReturn(0); 8779 } 8780 8781 #undef __FUNCT__ 8782 #define __FUNCT__ "MatCreateVecs" 8783 /*@C 8784 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8785 parallel layout 8786 8787 Collective on Mat 8788 8789 Input Parameter: 8790 . mat - the matrix 8791 8792 Output Parameter: 8793 + right - (optional) vector that the matrix can be multiplied against 8794 - left - (optional) vector that the matrix vector product can be stored in 8795 8796 Notes: 8797 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(). 8798 8799 Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8800 8801 Level: advanced 8802 8803 .seealso: MatCreate(), VecDestroy() 8804 @*/ 8805 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8806 { 8807 PetscErrorCode ierr; 8808 8809 PetscFunctionBegin; 8810 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8811 PetscValidType(mat,1); 8812 if (mat->ops->getvecs) { 8813 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8814 } else { 8815 PetscInt rbs,cbs; 8816 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8817 if (right) { 8818 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8819 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8820 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8821 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8822 ierr = VecSetType(*right,VECSTANDARD);CHKERRQ(ierr); 8823 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8824 } 8825 if (left) { 8826 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8827 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8828 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8829 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8830 ierr = VecSetType(*left,VECSTANDARD);CHKERRQ(ierr); 8831 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8832 } 8833 } 8834 PetscFunctionReturn(0); 8835 } 8836 8837 #undef __FUNCT__ 8838 #define __FUNCT__ "MatFactorInfoInitialize" 8839 /*@C 8840 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8841 with default values. 8842 8843 Not Collective 8844 8845 Input Parameters: 8846 . info - the MatFactorInfo data structure 8847 8848 8849 Notes: The solvers are generally used through the KSP and PC objects, for example 8850 PCLU, PCILU, PCCHOLESKY, PCICC 8851 8852 Level: developer 8853 8854 .seealso: MatFactorInfo 8855 8856 Developer Note: fortran interface is not autogenerated as the f90 8857 interface defintion cannot be generated correctly [due to MatFactorInfo] 8858 8859 @*/ 8860 8861 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8862 { 8863 PetscErrorCode ierr; 8864 8865 PetscFunctionBegin; 8866 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8867 PetscFunctionReturn(0); 8868 } 8869 8870 #undef __FUNCT__ 8871 #define __FUNCT__ "MatFactorSetSchurIS" 8872 /*@ 8873 MatFactorSetSchurIS - Set indices corresponding to the Schur complement 8874 8875 Collective on Mat 8876 8877 Input Parameters: 8878 + mat - the factored matrix 8879 - is - the index set defining the Schur indices (0-based) 8880 8881 Notes: 8882 8883 Level: developer 8884 8885 Concepts: 8886 8887 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement() 8888 8889 @*/ 8890 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 8891 { 8892 PetscErrorCode ierr,(*f)(Mat,IS); 8893 8894 PetscFunctionBegin; 8895 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8896 PetscValidType(mat,1); 8897 PetscValidHeaderSpecific(is,IS_CLASSID,2); 8898 PetscValidType(is,2); 8899 PetscCheckSameComm(mat,1,is,2); 8900 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 8901 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 8902 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"); 8903 ierr = (*f)(mat,is);CHKERRQ(ierr); 8904 PetscFunctionReturn(0); 8905 } 8906 8907 #undef __FUNCT__ 8908 #define __FUNCT__ "MatFactorCreateSchurComplement" 8909 /*@ 8910 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 8911 8912 Logically Collective on Mat 8913 8914 Input Parameters: 8915 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 8916 . *S - location where to return the Schur complement (MATDENSE) 8917 8918 Notes: 8919 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. 8920 If MatFactorInvertSchurComplement has been called, the routine gets back the inverse 8921 8922 Level: advanced 8923 8924 References: 8925 8926 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement() 8927 @*/ 8928 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S) 8929 { 8930 PetscErrorCode ierr; 8931 8932 PetscFunctionBegin; 8933 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8934 ierr = PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*),(F,S));CHKERRQ(ierr); 8935 PetscFunctionReturn(0); 8936 } 8937 8938 #undef __FUNCT__ 8939 #define __FUNCT__ "MatFactorGetSchurComplement" 8940 /*@ 8941 MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data 8942 8943 Logically Collective on Mat 8944 8945 Input Parameters: 8946 + F - the factored matrix obtained by calling MatGetFactor() 8947 . *S - location where to return the Schur complement (in MATDENSE format) 8948 8949 Notes: 8950 Schur complement mode is currently implemented for sequential matrices. 8951 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. 8952 The caller should call MatFactorRestoreSchurComplement when the object is no longer needed. 8953 8954 Level: advanced 8955 8956 References: 8957 8958 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement() 8959 @*/ 8960 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S) 8961 { 8962 PetscErrorCode ierr; 8963 8964 PetscFunctionBegin; 8965 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8966 ierr = PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*),(F,S));CHKERRQ(ierr); 8967 PetscFunctionReturn(0); 8968 } 8969 8970 #undef __FUNCT__ 8971 #define __FUNCT__ "MatFactorRestoreSchurComplement" 8972 /*@ 8973 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 8974 8975 Logically Collective on Mat 8976 8977 Input Parameters: 8978 + F - the factored matrix obtained by calling MatGetFactor() 8979 . *S - location where the Schur complement is stored 8980 8981 Notes: 8982 8983 Level: advanced 8984 8985 References: 8986 8987 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement() 8988 @*/ 8989 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S) 8990 { 8991 PetscErrorCode ierr; 8992 8993 PetscFunctionBegin; 8994 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8995 PetscValidHeaderSpecific(*S,MAT_CLASSID,1); 8996 ierr = MatDestroy(S);CHKERRQ(ierr); 8997 PetscFunctionReturn(0); 8998 } 8999 9000 #undef __FUNCT__ 9001 #define __FUNCT__ "MatFactorSolveSchurComplementTranspose" 9002 /*@ 9003 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 9004 9005 Logically Collective on Mat 9006 9007 Input Parameters: 9008 + F - the factored matrix obtained by calling MatGetFactor() 9009 . rhs - location where the right hand side of the Schur complement system is stored 9010 - sol - location where the solution of the Schur complement system has to be returned 9011 9012 Notes: 9013 The sizes of the vectors should match the size of the Schur complement 9014 9015 Level: advanced 9016 9017 References: 9018 9019 .seealso: MatGetFactor(), MatFactorSetSchurIS() 9020 @*/ 9021 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 9022 { 9023 PetscErrorCode ierr; 9024 9025 PetscFunctionBegin; 9026 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9027 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9028 PetscValidHeaderSpecific(sol,VEC_CLASSID,2); 9029 PetscCheckSameComm(F,1,rhs,2); 9030 PetscCheckSameComm(F,1,sol,3); 9031 ierr = PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));CHKERRQ(ierr); 9032 PetscFunctionReturn(0); 9033 } 9034 9035 #undef __FUNCT__ 9036 #define __FUNCT__ "MatFactorSolveSchurComplement" 9037 /*@ 9038 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9039 9040 Logically Collective on Mat 9041 9042 Input Parameters: 9043 + F - the factored matrix obtained by calling MatGetFactor() 9044 . rhs - location where the right hand side of the Schur complement system is stored 9045 - sol - location where the solution of the Schur complement system has to be returned 9046 9047 Notes: 9048 The sizes of the vectors should match the size of the Schur complement 9049 9050 Level: advanced 9051 9052 References: 9053 9054 .seealso: MatGetFactor(), MatFactorSetSchurIS() 9055 @*/ 9056 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9057 { 9058 PetscErrorCode ierr; 9059 9060 PetscFunctionBegin; 9061 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9062 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9063 PetscValidHeaderSpecific(sol,VEC_CLASSID,2); 9064 PetscCheckSameComm(F,1,rhs,2); 9065 PetscCheckSameComm(F,1,sol,3); 9066 ierr = PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));CHKERRQ(ierr); 9067 PetscFunctionReturn(0); 9068 } 9069 9070 #undef __FUNCT__ 9071 #define __FUNCT__ "MatFactorInvertSchurComplement" 9072 /*@ 9073 MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step 9074 9075 Logically Collective on Mat 9076 9077 Input Parameters: 9078 + F - the factored matrix obtained by calling MatGetFactor() 9079 9080 Notes: 9081 9082 Level: advanced 9083 9084 References: 9085 9086 .seealso: MatGetFactor(), MatFactorSetSchurIS() 9087 @*/ 9088 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9089 { 9090 PetscErrorCode ierr; 9091 9092 PetscFunctionBegin; 9093 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9094 ierr = PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));CHKERRQ(ierr); 9095 PetscFunctionReturn(0); 9096 } 9097 9098 9099 #undef __FUNCT__ 9100 #define __FUNCT__ "MatPtAP" 9101 /*@ 9102 MatPtAP - Creates the matrix product C = P^T * A * P 9103 9104 Neighbor-wise Collective on Mat 9105 9106 Input Parameters: 9107 + A - the matrix 9108 . P - the projection matrix 9109 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9110 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9111 if the result is a dense matrix this is irrelevent 9112 9113 Output Parameters: 9114 . C - the product matrix 9115 9116 Notes: 9117 C will be created and must be destroyed by the user with MatDestroy(). 9118 9119 This routine is currently only implemented for pairs of AIJ matrices and classes 9120 which inherit from AIJ. 9121 9122 Level: intermediate 9123 9124 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9125 @*/ 9126 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9127 { 9128 PetscErrorCode ierr; 9129 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9130 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9131 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9132 PetscBool viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE; 9133 9134 PetscFunctionBegin; 9135 ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);CHKERRQ(ierr); 9136 ierr = PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);CHKERRQ(ierr); 9137 9138 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9139 PetscValidType(A,1); 9140 MatCheckPreallocated(A,1); 9141 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9142 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9143 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9144 PetscValidType(P,2); 9145 MatCheckPreallocated(P,2); 9146 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9147 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9148 9149 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); 9150 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); 9151 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9152 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9153 9154 if (scall == MAT_REUSE_MATRIX) { 9155 PetscValidPointer(*C,5); 9156 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9157 if (viatranspose || viamatmatmatmult) { 9158 Mat Pt; 9159 ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr); 9160 if (viamatmatmatmult) { 9161 ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr); 9162 } else { 9163 Mat AP; 9164 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr); 9165 ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr); 9166 ierr = MatDestroy(&AP);CHKERRQ(ierr); 9167 } 9168 ierr = MatDestroy(&Pt);CHKERRQ(ierr); 9169 } else { 9170 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9171 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9172 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9173 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9174 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9175 } 9176 PetscFunctionReturn(0); 9177 } 9178 9179 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9180 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9181 9182 fA = A->ops->ptap; 9183 fP = P->ops->ptap; 9184 if (fP == fA) { 9185 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name); 9186 ptap = fA; 9187 } else { 9188 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9189 char ptapname[256]; 9190 ierr = PetscStrcpy(ptapname,"MatPtAP_");CHKERRQ(ierr); 9191 ierr = PetscStrcat(ptapname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9192 ierr = PetscStrcat(ptapname,"_");CHKERRQ(ierr); 9193 ierr = PetscStrcat(ptapname,((PetscObject)P)->type_name);CHKERRQ(ierr); 9194 ierr = PetscStrcat(ptapname,"_C");CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9195 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9196 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); 9197 } 9198 9199 if (viatranspose || viamatmatmatmult) { 9200 Mat Pt; 9201 ierr = MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);CHKERRQ(ierr); 9202 if (viamatmatmatmult) { 9203 ierr = MatMatMatMult(Pt,A,P,scall,fill,C);CHKERRQ(ierr); 9204 ierr = PetscInfo(*C,"MatPtAP via MatMatMatMult\n");CHKERRQ(ierr); 9205 } else { 9206 Mat AP; 9207 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);CHKERRQ(ierr); 9208 ierr = MatMatMult(Pt,AP,scall,fill,C);CHKERRQ(ierr); 9209 ierr = MatDestroy(&AP);CHKERRQ(ierr); 9210 ierr = PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");CHKERRQ(ierr); 9211 } 9212 ierr = MatDestroy(&Pt);CHKERRQ(ierr); 9213 } else { 9214 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9215 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9216 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9217 } 9218 PetscFunctionReturn(0); 9219 } 9220 9221 #undef __FUNCT__ 9222 #define __FUNCT__ "MatPtAPNumeric" 9223 /*@ 9224 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9225 9226 Neighbor-wise Collective on Mat 9227 9228 Input Parameters: 9229 + A - the matrix 9230 - P - the projection matrix 9231 9232 Output Parameters: 9233 . C - the product matrix 9234 9235 Notes: 9236 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9237 the user using MatDeatroy(). 9238 9239 This routine is currently only implemented for pairs of AIJ matrices and classes 9240 which inherit from AIJ. C will be of type MATAIJ. 9241 9242 Level: intermediate 9243 9244 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9245 @*/ 9246 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9247 { 9248 PetscErrorCode ierr; 9249 9250 PetscFunctionBegin; 9251 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9252 PetscValidType(A,1); 9253 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9254 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9255 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9256 PetscValidType(P,2); 9257 MatCheckPreallocated(P,2); 9258 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9259 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9260 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9261 PetscValidType(C,3); 9262 MatCheckPreallocated(C,3); 9263 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9264 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); 9265 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); 9266 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); 9267 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); 9268 MatCheckPreallocated(A,1); 9269 9270 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9271 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9272 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9273 PetscFunctionReturn(0); 9274 } 9275 9276 #undef __FUNCT__ 9277 #define __FUNCT__ "MatPtAPSymbolic" 9278 /*@ 9279 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9280 9281 Neighbor-wise Collective on Mat 9282 9283 Input Parameters: 9284 + A - the matrix 9285 - P - the projection matrix 9286 9287 Output Parameters: 9288 . C - the (i,j) structure of the product matrix 9289 9290 Notes: 9291 C will be created and must be destroyed by the user with MatDestroy(). 9292 9293 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9294 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9295 this (i,j) structure by calling MatPtAPNumeric(). 9296 9297 Level: intermediate 9298 9299 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9300 @*/ 9301 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9302 { 9303 PetscErrorCode ierr; 9304 9305 PetscFunctionBegin; 9306 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9307 PetscValidType(A,1); 9308 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9309 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9310 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9311 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9312 PetscValidType(P,2); 9313 MatCheckPreallocated(P,2); 9314 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9315 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9316 PetscValidPointer(C,3); 9317 9318 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); 9319 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); 9320 MatCheckPreallocated(A,1); 9321 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9322 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9323 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9324 9325 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9326 PetscFunctionReturn(0); 9327 } 9328 9329 #undef __FUNCT__ 9330 #define __FUNCT__ "MatRARt" 9331 /*@ 9332 MatRARt - Creates the matrix product C = R * A * R^T 9333 9334 Neighbor-wise Collective on Mat 9335 9336 Input Parameters: 9337 + A - the matrix 9338 . R - the projection matrix 9339 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9340 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9341 if the result is a dense matrix this is irrelevent 9342 9343 Output Parameters: 9344 . C - the product matrix 9345 9346 Notes: 9347 C will be created and must be destroyed by the user with MatDestroy(). 9348 9349 This routine is currently only implemented for pairs of AIJ matrices and classes 9350 which inherit from AIJ. 9351 9352 Level: intermediate 9353 9354 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9355 @*/ 9356 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9357 { 9358 PetscErrorCode ierr; 9359 9360 PetscFunctionBegin; 9361 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9362 PetscValidType(A,1); 9363 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9364 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9365 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9366 PetscValidType(R,2); 9367 MatCheckPreallocated(R,2); 9368 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9369 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9370 PetscValidPointer(C,3); 9371 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); 9372 9373 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9374 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9375 MatCheckPreallocated(A,1); 9376 9377 if (!A->ops->rart) { 9378 MatType mattype; 9379 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 9380 SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype); 9381 } 9382 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9383 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9384 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9385 PetscFunctionReturn(0); 9386 } 9387 9388 #undef __FUNCT__ 9389 #define __FUNCT__ "MatRARtNumeric" 9390 /*@ 9391 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9392 9393 Neighbor-wise Collective on Mat 9394 9395 Input Parameters: 9396 + A - the matrix 9397 - R - the projection matrix 9398 9399 Output Parameters: 9400 . C - the product matrix 9401 9402 Notes: 9403 C must have been created by calling MatRARtSymbolic and must be destroyed by 9404 the user using MatDestroy(). 9405 9406 This routine is currently only implemented for pairs of AIJ matrices and classes 9407 which inherit from AIJ. C will be of type MATAIJ. 9408 9409 Level: intermediate 9410 9411 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9412 @*/ 9413 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9414 { 9415 PetscErrorCode ierr; 9416 9417 PetscFunctionBegin; 9418 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9419 PetscValidType(A,1); 9420 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9421 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9422 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9423 PetscValidType(R,2); 9424 MatCheckPreallocated(R,2); 9425 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9426 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9427 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9428 PetscValidType(C,3); 9429 MatCheckPreallocated(C,3); 9430 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9431 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); 9432 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); 9433 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); 9434 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); 9435 MatCheckPreallocated(A,1); 9436 9437 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9438 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9439 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9440 PetscFunctionReturn(0); 9441 } 9442 9443 #undef __FUNCT__ 9444 #define __FUNCT__ "MatRARtSymbolic" 9445 /*@ 9446 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9447 9448 Neighbor-wise Collective on Mat 9449 9450 Input Parameters: 9451 + A - the matrix 9452 - R - the projection matrix 9453 9454 Output Parameters: 9455 . C - the (i,j) structure of the product matrix 9456 9457 Notes: 9458 C will be created and must be destroyed by the user with MatDestroy(). 9459 9460 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9461 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9462 this (i,j) structure by calling MatRARtNumeric(). 9463 9464 Level: intermediate 9465 9466 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9467 @*/ 9468 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9469 { 9470 PetscErrorCode ierr; 9471 9472 PetscFunctionBegin; 9473 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9474 PetscValidType(A,1); 9475 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9476 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9477 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9478 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9479 PetscValidType(R,2); 9480 MatCheckPreallocated(R,2); 9481 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9482 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9483 PetscValidPointer(C,3); 9484 9485 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); 9486 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); 9487 MatCheckPreallocated(A,1); 9488 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9489 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9490 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9491 9492 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9493 PetscFunctionReturn(0); 9494 } 9495 9496 #undef __FUNCT__ 9497 #define __FUNCT__ "MatMatMult" 9498 /*@ 9499 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9500 9501 Neighbor-wise Collective on Mat 9502 9503 Input Parameters: 9504 + A - the left matrix 9505 . B - the right matrix 9506 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9507 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9508 if the result is a dense matrix this is irrelevent 9509 9510 Output Parameters: 9511 . C - the product matrix 9512 9513 Notes: 9514 Unless scall is MAT_REUSE_MATRIX C will be created. 9515 9516 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9517 9518 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9519 actually needed. 9520 9521 If you have many matrices with the same non-zero structure to multiply, you 9522 should either 9523 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9524 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9525 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 9526 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9527 9528 Level: intermediate 9529 9530 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9531 @*/ 9532 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9533 { 9534 PetscErrorCode ierr; 9535 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9536 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9537 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9538 9539 PetscFunctionBegin; 9540 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9541 PetscValidType(A,1); 9542 MatCheckPreallocated(A,1); 9543 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9544 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9545 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9546 PetscValidType(B,2); 9547 MatCheckPreallocated(B,2); 9548 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9549 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9550 PetscValidPointer(C,3); 9551 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); 9552 if (scall == MAT_REUSE_MATRIX) { 9553 PetscValidPointer(*C,5); 9554 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9555 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9556 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9557 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9558 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9559 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9560 PetscFunctionReturn(0); 9561 } 9562 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9563 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9564 9565 fA = A->ops->matmult; 9566 fB = B->ops->matmult; 9567 if (fB == fA) { 9568 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 9569 mult = fB; 9570 } else { 9571 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9572 char multname[256]; 9573 ierr = PetscStrcpy(multname,"MatMatMult_");CHKERRQ(ierr); 9574 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9575 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 9576 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 9577 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9578 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9579 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); 9580 } 9581 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9582 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9583 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9584 PetscFunctionReturn(0); 9585 } 9586 9587 #undef __FUNCT__ 9588 #define __FUNCT__ "MatMatMultSymbolic" 9589 /*@ 9590 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9591 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9592 9593 Neighbor-wise Collective on Mat 9594 9595 Input Parameters: 9596 + A - the left matrix 9597 . B - the right matrix 9598 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9599 if C is a dense matrix this is irrelevent 9600 9601 Output Parameters: 9602 . C - the product matrix 9603 9604 Notes: 9605 Unless scall is MAT_REUSE_MATRIX C will be created. 9606 9607 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9608 actually needed. 9609 9610 This routine is currently implemented for 9611 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9612 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9613 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9614 9615 Level: intermediate 9616 9617 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173 9618 We should incorporate them into PETSc. 9619 9620 .seealso: MatMatMult(), MatMatMultNumeric() 9621 @*/ 9622 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9623 { 9624 PetscErrorCode ierr; 9625 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9626 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9627 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9628 9629 PetscFunctionBegin; 9630 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9631 PetscValidType(A,1); 9632 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9633 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9634 9635 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9636 PetscValidType(B,2); 9637 MatCheckPreallocated(B,2); 9638 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9639 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9640 PetscValidPointer(C,3); 9641 9642 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); 9643 if (fill == PETSC_DEFAULT) fill = 2.0; 9644 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9645 MatCheckPreallocated(A,1); 9646 9647 Asymbolic = A->ops->matmultsymbolic; 9648 Bsymbolic = B->ops->matmultsymbolic; 9649 if (Asymbolic == Bsymbolic) { 9650 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 9651 symbolic = Bsymbolic; 9652 } else { /* dispatch based on the type of A and B */ 9653 char symbolicname[256]; 9654 ierr = PetscStrcpy(symbolicname,"MatMatMultSymbolic_");CHKERRQ(ierr); 9655 ierr = PetscStrcat(symbolicname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9656 ierr = PetscStrcat(symbolicname,"_");CHKERRQ(ierr); 9657 ierr = PetscStrcat(symbolicname,((PetscObject)B)->type_name);CHKERRQ(ierr); 9658 ierr = PetscStrcat(symbolicname,"_C");CHKERRQ(ierr); 9659 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9660 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); 9661 } 9662 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9663 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 9664 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9665 PetscFunctionReturn(0); 9666 } 9667 9668 #undef __FUNCT__ 9669 #define __FUNCT__ "MatMatMultNumeric" 9670 /*@ 9671 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9672 Call this routine after first calling MatMatMultSymbolic(). 9673 9674 Neighbor-wise Collective on Mat 9675 9676 Input Parameters: 9677 + A - the left matrix 9678 - B - the right matrix 9679 9680 Output Parameters: 9681 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9682 9683 Notes: 9684 C must have been created with MatMatMultSymbolic(). 9685 9686 This routine is currently implemented for 9687 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9688 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9689 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9690 9691 Level: intermediate 9692 9693 .seealso: MatMatMult(), MatMatMultSymbolic() 9694 @*/ 9695 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9696 { 9697 PetscErrorCode ierr; 9698 9699 PetscFunctionBegin; 9700 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 9701 PetscFunctionReturn(0); 9702 } 9703 9704 #undef __FUNCT__ 9705 #define __FUNCT__ "MatMatTransposeMult" 9706 /*@ 9707 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9708 9709 Neighbor-wise Collective on Mat 9710 9711 Input Parameters: 9712 + A - the left matrix 9713 . B - the right matrix 9714 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9715 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9716 9717 Output Parameters: 9718 . C - the product matrix 9719 9720 Notes: 9721 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9722 9723 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9724 9725 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9726 actually needed. 9727 9728 This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ. 9729 9730 Level: intermediate 9731 9732 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9733 @*/ 9734 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9735 { 9736 PetscErrorCode ierr; 9737 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9738 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9739 9740 PetscFunctionBegin; 9741 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9742 PetscValidType(A,1); 9743 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9744 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9745 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9746 PetscValidType(B,2); 9747 MatCheckPreallocated(B,2); 9748 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9749 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9750 PetscValidPointer(C,3); 9751 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); 9752 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9753 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9754 MatCheckPreallocated(A,1); 9755 9756 fA = A->ops->mattransposemult; 9757 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9758 fB = B->ops->mattransposemult; 9759 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9760 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); 9761 9762 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9763 if (scall == MAT_INITIAL_MATRIX) { 9764 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9765 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9766 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9767 } 9768 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9769 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 9770 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9771 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9772 PetscFunctionReturn(0); 9773 } 9774 9775 #undef __FUNCT__ 9776 #define __FUNCT__ "MatTransposeMatMult" 9777 /*@ 9778 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9779 9780 Neighbor-wise Collective on Mat 9781 9782 Input Parameters: 9783 + A - the left matrix 9784 . B - the right matrix 9785 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9786 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9787 9788 Output Parameters: 9789 . C - the product matrix 9790 9791 Notes: 9792 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9793 9794 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9795 9796 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9797 actually needed. 9798 9799 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9800 which inherit from SeqAIJ. C will be of same type as the input matrices. 9801 9802 Level: intermediate 9803 9804 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 9805 @*/ 9806 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9807 { 9808 PetscErrorCode ierr; 9809 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9810 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9811 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 9812 9813 PetscFunctionBegin; 9814 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9815 PetscValidType(A,1); 9816 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9817 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9818 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9819 PetscValidType(B,2); 9820 MatCheckPreallocated(B,2); 9821 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9822 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9823 PetscValidPointer(C,3); 9824 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); 9825 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9826 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9827 MatCheckPreallocated(A,1); 9828 9829 fA = A->ops->transposematmult; 9830 fB = B->ops->transposematmult; 9831 if (fB==fA) { 9832 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9833 transposematmult = fA; 9834 } else { 9835 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9836 char multname[256]; 9837 ierr = PetscStrcpy(multname,"MatTransposeMatMult_");CHKERRQ(ierr); 9838 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9839 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 9840 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 9841 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9842 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 9843 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); 9844 } 9845 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9846 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 9847 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9848 PetscFunctionReturn(0); 9849 } 9850 9851 #undef __FUNCT__ 9852 #define __FUNCT__ "MatMatMatMult" 9853 /*@ 9854 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9855 9856 Neighbor-wise Collective on Mat 9857 9858 Input Parameters: 9859 + A - the left matrix 9860 . B - the middle matrix 9861 . C - the right matrix 9862 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9863 - 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 9864 if the result is a dense matrix this is irrelevent 9865 9866 Output Parameters: 9867 . D - the product matrix 9868 9869 Notes: 9870 Unless scall is MAT_REUSE_MATRIX D will be created. 9871 9872 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9873 9874 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9875 actually needed. 9876 9877 If you have many matrices with the same non-zero structure to multiply, you 9878 should use MAT_REUSE_MATRIX in all calls but the first or 9879 9880 Level: intermediate 9881 9882 .seealso: MatMatMult, MatPtAP() 9883 @*/ 9884 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9885 { 9886 PetscErrorCode ierr; 9887 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9888 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9889 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9890 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9891 9892 PetscFunctionBegin; 9893 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9894 PetscValidType(A,1); 9895 MatCheckPreallocated(A,1); 9896 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9897 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9898 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9899 PetscValidType(B,2); 9900 MatCheckPreallocated(B,2); 9901 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9902 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9903 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9904 PetscValidPointer(C,3); 9905 MatCheckPreallocated(C,3); 9906 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9907 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9908 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); 9909 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); 9910 if (scall == MAT_REUSE_MATRIX) { 9911 PetscValidPointer(*D,6); 9912 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 9913 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9914 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9915 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9916 PetscFunctionReturn(0); 9917 } 9918 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9919 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9920 9921 fA = A->ops->matmatmult; 9922 fB = B->ops->matmatmult; 9923 fC = C->ops->matmatmult; 9924 if (fA == fB && fA == fC) { 9925 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9926 mult = fA; 9927 } else { 9928 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 9929 char multname[256]; 9930 ierr = PetscStrcpy(multname,"MatMatMatMult_");CHKERRQ(ierr); 9931 ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr); 9932 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 9933 ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr); 9934 ierr = PetscStrcat(multname,"_");CHKERRQ(ierr); 9935 ierr = PetscStrcat(multname,((PetscObject)C)->type_name);CHKERRQ(ierr); 9936 ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); 9937 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9938 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); 9939 } 9940 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9941 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9942 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9943 PetscFunctionReturn(0); 9944 } 9945 9946 #undef __FUNCT__ 9947 #define __FUNCT__ "MatCreateRedundantMatrix" 9948 /*@ 9949 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9950 9951 Collective on Mat 9952 9953 Input Parameters: 9954 + mat - the matrix 9955 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 9956 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 9957 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9958 9959 Output Parameter: 9960 . matredundant - redundant matrix 9961 9962 Notes: 9963 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 9964 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 9965 9966 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 9967 calling it. 9968 9969 Level: advanced 9970 9971 Concepts: subcommunicator 9972 Concepts: duplicate matrix 9973 9974 .seealso: MatDestroy() 9975 @*/ 9976 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 9977 { 9978 PetscErrorCode ierr; 9979 MPI_Comm comm; 9980 PetscMPIInt size; 9981 PetscInt mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 9982 Mat_Redundant *redund=NULL; 9983 PetscSubcomm psubcomm=NULL; 9984 MPI_Comm subcomm_in=subcomm; 9985 Mat *matseq; 9986 IS isrow,iscol; 9987 PetscBool newsubcomm=PETSC_FALSE; 9988 9989 PetscFunctionBegin; 9990 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 9991 if (size == 1 || nsubcomm == 1) { 9992 if (reuse == MAT_INITIAL_MATRIX) { 9993 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 9994 } else { 9995 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 9996 } 9997 PetscFunctionReturn(0); 9998 } 9999 10000 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10001 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10002 PetscValidPointer(*matredundant,5); 10003 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10004 } 10005 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10006 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10007 MatCheckPreallocated(mat,1); 10008 10009 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10010 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10011 /* create psubcomm, then get subcomm */ 10012 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10013 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10014 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 10015 10016 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10017 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10018 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10019 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10020 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10021 newsubcomm = PETSC_TRUE; 10022 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10023 } 10024 10025 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10026 if (reuse == MAT_INITIAL_MATRIX) { 10027 mloc_sub = PETSC_DECIDE; 10028 if (bs < 1) { 10029 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10030 } else { 10031 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10032 } 10033 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10034 rstart = rend - mloc_sub; 10035 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10036 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10037 } else { /* reuse == MAT_REUSE_MATRIX */ 10038 /* retrieve subcomm */ 10039 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10040 redund = (*matredundant)->redundant; 10041 isrow = redund->isrow; 10042 iscol = redund->iscol; 10043 matseq = redund->matseq; 10044 } 10045 ierr = MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10046 10047 /* get matredundant over subcomm */ 10048 if (reuse == MAT_INITIAL_MATRIX) { 10049 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);CHKERRQ(ierr); 10050 10051 /* create a supporting struct and attach it to C for reuse */ 10052 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10053 (*matredundant)->redundant = redund; 10054 redund->isrow = isrow; 10055 redund->iscol = iscol; 10056 redund->matseq = matseq; 10057 if (newsubcomm) { 10058 redund->subcomm = subcomm; 10059 } else { 10060 redund->subcomm = MPI_COMM_NULL; 10061 } 10062 } else { 10063 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10064 } 10065 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10066 PetscFunctionReturn(0); 10067 } 10068 10069 #undef __FUNCT__ 10070 #define __FUNCT__ "MatGetMultiProcBlock" 10071 /*@C 10072 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10073 a given 'mat' object. Each submatrix can span multiple procs. 10074 10075 Collective on Mat 10076 10077 Input Parameters: 10078 + mat - the matrix 10079 . subcomm - the subcommunicator obtained by com_split(comm) 10080 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10081 10082 Output Parameter: 10083 . subMat - 'parallel submatrices each spans a given subcomm 10084 10085 Notes: 10086 The submatrix partition across processors is dictated by 'subComm' a 10087 communicator obtained by com_split(comm). The comm_split 10088 is not restriced to be grouped with consecutive original ranks. 10089 10090 Due the comm_split() usage, the parallel layout of the submatrices 10091 map directly to the layout of the original matrix [wrt the local 10092 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10093 into the 'DiagonalMat' of the subMat, hence it is used directly from 10094 the subMat. However the offDiagMat looses some columns - and this is 10095 reconstructed with MatSetValues() 10096 10097 Level: advanced 10098 10099 Concepts: subcommunicator 10100 Concepts: submatrices 10101 10102 .seealso: MatGetSubMatrices() 10103 @*/ 10104 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10105 { 10106 PetscErrorCode ierr; 10107 PetscMPIInt commsize,subCommSize; 10108 10109 PetscFunctionBegin; 10110 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10111 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10112 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10113 10114 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10115 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10116 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10117 PetscFunctionReturn(0); 10118 } 10119 10120 #undef __FUNCT__ 10121 #define __FUNCT__ "MatGetLocalSubMatrix" 10122 /*@ 10123 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10124 10125 Not Collective 10126 10127 Input Arguments: 10128 mat - matrix to extract local submatrix from 10129 isrow - local row indices for submatrix 10130 iscol - local column indices for submatrix 10131 10132 Output Arguments: 10133 submat - the submatrix 10134 10135 Level: intermediate 10136 10137 Notes: 10138 The submat should be returned with MatRestoreLocalSubMatrix(). 10139 10140 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10141 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10142 10143 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10144 MatSetValuesBlockedLocal() will also be implemented. 10145 10146 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10147 matrices obtained with DMCreateMat() generally already have the local to global mapping provided. 10148 10149 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10150 @*/ 10151 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10152 { 10153 PetscErrorCode ierr; 10154 10155 PetscFunctionBegin; 10156 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10157 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10158 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10159 PetscCheckSameComm(isrow,2,iscol,3); 10160 PetscValidPointer(submat,4); 10161 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10162 10163 if (mat->ops->getlocalsubmatrix) { 10164 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10165 } else { 10166 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10167 } 10168 PetscFunctionReturn(0); 10169 } 10170 10171 #undef __FUNCT__ 10172 #define __FUNCT__ "MatRestoreLocalSubMatrix" 10173 /*@ 10174 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10175 10176 Not Collective 10177 10178 Input Arguments: 10179 mat - matrix to extract local submatrix from 10180 isrow - local row indices for submatrix 10181 iscol - local column indices for submatrix 10182 submat - the submatrix 10183 10184 Level: intermediate 10185 10186 .seealso: MatGetLocalSubMatrix() 10187 @*/ 10188 PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10189 { 10190 PetscErrorCode ierr; 10191 10192 PetscFunctionBegin; 10193 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10194 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10195 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10196 PetscCheckSameComm(isrow,2,iscol,3); 10197 PetscValidPointer(submat,4); 10198 if (*submat) { 10199 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10200 } 10201 10202 if (mat->ops->restorelocalsubmatrix) { 10203 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10204 } else { 10205 ierr = MatDestroy(submat);CHKERRQ(ierr); 10206 } 10207 *submat = NULL; 10208 PetscFunctionReturn(0); 10209 } 10210 10211 /* --------------------------------------------------------*/ 10212 #undef __FUNCT__ 10213 #define __FUNCT__ "MatFindZeroDiagonals" 10214 /*@ 10215 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix 10216 10217 Collective on Mat 10218 10219 Input Parameter: 10220 . mat - the matrix 10221 10222 Output Parameter: 10223 . is - if any rows have zero diagonals this contains the list of them 10224 10225 Level: developer 10226 10227 Concepts: matrix-vector product 10228 10229 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10230 @*/ 10231 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10232 { 10233 PetscErrorCode ierr; 10234 10235 PetscFunctionBegin; 10236 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10237 PetscValidType(mat,1); 10238 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10239 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10240 10241 if (!mat->ops->findzerodiagonals) { 10242 Vec diag; 10243 const PetscScalar *a; 10244 PetscInt *rows; 10245 PetscInt rStart, rEnd, r, nrow = 0; 10246 10247 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10248 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10249 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10250 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10251 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10252 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10253 nrow = 0; 10254 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10255 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10256 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10257 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10258 } else { 10259 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10260 } 10261 PetscFunctionReturn(0); 10262 } 10263 10264 #undef __FUNCT__ 10265 #define __FUNCT__ "MatFindOffBlockDiagonalEntries" 10266 /*@ 10267 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10268 10269 Collective on Mat 10270 10271 Input Parameter: 10272 . mat - the matrix 10273 10274 Output Parameter: 10275 . is - contains the list of rows with off block diagonal entries 10276 10277 Level: developer 10278 10279 Concepts: matrix-vector product 10280 10281 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10282 @*/ 10283 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10284 { 10285 PetscErrorCode ierr; 10286 10287 PetscFunctionBegin; 10288 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10289 PetscValidType(mat,1); 10290 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10291 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10292 10293 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10294 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10295 PetscFunctionReturn(0); 10296 } 10297 10298 #undef __FUNCT__ 10299 #define __FUNCT__ "MatInvertBlockDiagonal" 10300 /*@C 10301 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10302 10303 Collective on Mat 10304 10305 Input Parameters: 10306 . mat - the matrix 10307 10308 Output Parameters: 10309 . values - the block inverses in column major order (FORTRAN-like) 10310 10311 Note: 10312 This routine is not available from Fortran. 10313 10314 Level: advanced 10315 @*/ 10316 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10317 { 10318 PetscErrorCode ierr; 10319 10320 PetscFunctionBegin; 10321 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10322 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10323 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10324 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10325 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10326 PetscFunctionReturn(0); 10327 } 10328 10329 #undef __FUNCT__ 10330 #define __FUNCT__ "MatTransposeColoringDestroy" 10331 /*@C 10332 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10333 via MatTransposeColoringCreate(). 10334 10335 Collective on MatTransposeColoring 10336 10337 Input Parameter: 10338 . c - coloring context 10339 10340 Level: intermediate 10341 10342 .seealso: MatTransposeColoringCreate() 10343 @*/ 10344 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10345 { 10346 PetscErrorCode ierr; 10347 MatTransposeColoring matcolor=*c; 10348 10349 PetscFunctionBegin; 10350 if (!matcolor) PetscFunctionReturn(0); 10351 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10352 10353 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10354 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10355 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10356 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10357 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10358 if (matcolor->brows>0) { 10359 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10360 } 10361 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10362 PetscFunctionReturn(0); 10363 } 10364 10365 #undef __FUNCT__ 10366 #define __FUNCT__ "MatTransColoringApplySpToDen" 10367 /*@C 10368 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10369 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10370 MatTransposeColoring to sparse B. 10371 10372 Collective on MatTransposeColoring 10373 10374 Input Parameters: 10375 + B - sparse matrix B 10376 . Btdense - symbolic dense matrix B^T 10377 - coloring - coloring context created with MatTransposeColoringCreate() 10378 10379 Output Parameter: 10380 . Btdense - dense matrix B^T 10381 10382 Level: advanced 10383 10384 Notes: These are used internally for some implementations of MatRARt() 10385 10386 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10387 10388 .keywords: coloring 10389 @*/ 10390 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10391 { 10392 PetscErrorCode ierr; 10393 10394 PetscFunctionBegin; 10395 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10396 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10397 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10398 10399 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10400 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10401 PetscFunctionReturn(0); 10402 } 10403 10404 #undef __FUNCT__ 10405 #define __FUNCT__ "MatTransColoringApplyDenToSp" 10406 /*@C 10407 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10408 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10409 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10410 Csp from Cden. 10411 10412 Collective on MatTransposeColoring 10413 10414 Input Parameters: 10415 + coloring - coloring context created with MatTransposeColoringCreate() 10416 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10417 10418 Output Parameter: 10419 . Csp - sparse matrix 10420 10421 Level: advanced 10422 10423 Notes: These are used internally for some implementations of MatRARt() 10424 10425 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10426 10427 .keywords: coloring 10428 @*/ 10429 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10430 { 10431 PetscErrorCode ierr; 10432 10433 PetscFunctionBegin; 10434 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10435 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10436 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10437 10438 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10439 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10440 PetscFunctionReturn(0); 10441 } 10442 10443 #undef __FUNCT__ 10444 #define __FUNCT__ "MatTransposeColoringCreate" 10445 /*@C 10446 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10447 10448 Collective on Mat 10449 10450 Input Parameters: 10451 + mat - the matrix product C 10452 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10453 10454 Output Parameter: 10455 . color - the new coloring context 10456 10457 Level: intermediate 10458 10459 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10460 MatTransColoringApplyDenToSp() 10461 @*/ 10462 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10463 { 10464 MatTransposeColoring c; 10465 MPI_Comm comm; 10466 PetscErrorCode ierr; 10467 10468 PetscFunctionBegin; 10469 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10470 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10471 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10472 10473 c->ctype = iscoloring->ctype; 10474 if (mat->ops->transposecoloringcreate) { 10475 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10476 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10477 10478 *color = c; 10479 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10480 PetscFunctionReturn(0); 10481 } 10482 10483 #undef __FUNCT__ 10484 #define __FUNCT__ "MatGetNonzeroState" 10485 /*@ 10486 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10487 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10488 same, otherwise it will be larger 10489 10490 Not Collective 10491 10492 Input Parameter: 10493 . A - the matrix 10494 10495 Output Parameter: 10496 . state - the current state 10497 10498 Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10499 different matrices 10500 10501 Level: intermediate 10502 10503 @*/ 10504 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10505 { 10506 PetscFunctionBegin; 10507 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10508 *state = mat->nonzerostate; 10509 PetscFunctionReturn(0); 10510 } 10511 10512 #undef __FUNCT__ 10513 #define __FUNCT__ "MatCreateMPIMatConcatenateSeqMat" 10514 /*@ 10515 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10516 matrices from each processor 10517 10518 Collective on MPI_Comm 10519 10520 Input Parameters: 10521 + comm - the communicators the parallel matrix will live on 10522 . seqmat - the input sequential matrices 10523 . n - number of local columns (or PETSC_DECIDE) 10524 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10525 10526 Output Parameter: 10527 . mpimat - the parallel matrix generated 10528 10529 Level: advanced 10530 10531 Notes: The number of columns of the matrix in EACH processor MUST be the same. 10532 10533 @*/ 10534 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10535 { 10536 PetscErrorCode ierr; 10537 PetscMPIInt size; 10538 10539 PetscFunctionBegin; 10540 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10541 if (size == 1) { 10542 if (reuse == MAT_INITIAL_MATRIX) { 10543 ierr = MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat);CHKERRQ(ierr); 10544 } else { 10545 ierr = MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10546 } 10547 PetscFunctionReturn(0); 10548 } 10549 10550 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10551 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10552 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10553 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10554 PetscFunctionReturn(0); 10555 } 10556 10557 #undef __FUNCT__ 10558 #define __FUNCT__ "MatSubdomainsCreateCoalesce" 10559 /*@ 10560 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10561 ranks' ownership ranges. 10562 10563 Collective on A 10564 10565 Input Parameters: 10566 + A - the matrix to create subdomains from 10567 - N - requested number of subdomains 10568 10569 10570 Output Parameters: 10571 + n - number of subdomains resulting on this rank 10572 - iss - IS list with indices of subdomains on this rank 10573 10574 Level: advanced 10575 10576 Notes: number of subdomains must be smaller than the communicator size 10577 @*/ 10578 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10579 { 10580 MPI_Comm comm,subcomm; 10581 PetscMPIInt size,rank,color; 10582 PetscInt rstart,rend,k; 10583 PetscErrorCode ierr; 10584 10585 PetscFunctionBegin; 10586 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10587 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10588 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10589 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); 10590 *n = 1; 10591 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10592 color = rank/k; 10593 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10594 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10595 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10596 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10597 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10598 PetscFunctionReturn(0); 10599 } 10600