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