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