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