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