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