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