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