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