1 2 /* 3 This is where the abstract matrix operations are defined 4 */ 5 6 #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 7 #include <petsc/private/isimpl.h> 8 #include <petsc/private/vecimpl.h> 9 10 /* Logging support */ 11 PetscClassId MAT_CLASSID; 12 PetscClassId MAT_COLORING_CLASSID; 13 PetscClassId MAT_FDCOLORING_CLASSID; 14 PetscClassId MAT_TRANSPOSECOLORING_CLASSID; 15 16 PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose; 17 PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve,MAT_MatTrSolve; 18 PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic; 19 PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor; 20 PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin; 21 PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure; 22 PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_PartitioningND, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate; 23 PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat; 24 PetscLogEvent MAT_TransposeColoringCreate; 25 PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric; 26 PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric; 27 PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric; 28 PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric; 29 PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric; 30 PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd; 31 PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_GetBrowsOfAcols; 32 PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym; 33 PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure; 34 PetscLogEvent MAT_GetMultiProcBlock; 35 PetscLogEvent MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch; 36 PetscLogEvent MAT_ViennaCLCopyToGPU; 37 PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom; 38 PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights; 39 40 const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0}; 41 42 /*@ 43 MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated but not been assembled it randomly selects appropriate locations 44 45 Logically Collective on Mat 46 47 Input Parameters: 48 + x - the matrix 49 - rctx - the random number context, formed by PetscRandomCreate(), or NULL and 50 it will create one internally. 51 52 Output Parameter: 53 . x - the matrix 54 55 Example of Usage: 56 .vb 57 PetscRandomCreate(PETSC_COMM_WORLD,&rctx); 58 MatSetRandom(x,rctx); 59 PetscRandomDestroy(rctx); 60 .ve 61 62 Level: intermediate 63 64 65 .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy() 66 @*/ 67 PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx) 68 { 69 PetscErrorCode ierr; 70 PetscRandom randObj = NULL; 71 72 PetscFunctionBegin; 73 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 74 if (rctx) PetscValidHeaderSpecific(rctx,PETSC_RANDOM_CLASSID,2); 75 PetscValidType(x,1); 76 77 if (!x->ops->setrandom) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Mat type %s",((PetscObject)x)->type_name); 78 79 if (!rctx) { 80 MPI_Comm comm; 81 ierr = PetscObjectGetComm((PetscObject)x,&comm);CHKERRQ(ierr); 82 ierr = PetscRandomCreate(comm,&randObj);CHKERRQ(ierr); 83 ierr = PetscRandomSetFromOptions(randObj);CHKERRQ(ierr); 84 rctx = randObj; 85 } 86 87 ierr = PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 88 ierr = (*x->ops->setrandom)(x,rctx);CHKERRQ(ierr); 89 ierr = PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);CHKERRQ(ierr); 90 91 ierr = MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 92 ierr = MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 93 ierr = PetscRandomDestroy(&randObj);CHKERRQ(ierr); 94 PetscFunctionReturn(0); 95 } 96 97 /*@ 98 MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in 99 100 Logically Collective on Mat 101 102 Input Parameters: 103 . mat - the factored matrix 104 105 Output Parameter: 106 + pivot - the pivot value computed 107 - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes 108 the share the matrix 109 110 Level: advanced 111 112 Notes: 113 This routine does not work for factorizations done with external packages. 114 This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT 115 116 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 117 118 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 119 @*/ 120 PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row) 121 { 122 PetscFunctionBegin; 123 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 124 *pivot = mat->factorerror_zeropivot_value; 125 *row = mat->factorerror_zeropivot_row; 126 PetscFunctionReturn(0); 127 } 128 129 /*@ 130 MatFactorGetError - gets the error code from a factorization 131 132 Logically Collective on Mat 133 134 Input Parameters: 135 . mat - the factored matrix 136 137 Output Parameter: 138 . err - the error code 139 140 Level: advanced 141 142 Notes: 143 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 144 145 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot() 146 @*/ 147 PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err) 148 { 149 PetscFunctionBegin; 150 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 151 *err = mat->factorerrortype; 152 PetscFunctionReturn(0); 153 } 154 155 /*@ 156 MatFactorClearError - clears the error code in a factorization 157 158 Logically Collective on Mat 159 160 Input Parameter: 161 . mat - the factored matrix 162 163 Level: developer 164 165 Notes: 166 This can be called on non-factored matrices that come from, for example, matrices used in SOR. 167 168 .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot() 169 @*/ 170 PetscErrorCode MatFactorClearError(Mat mat) 171 { 172 PetscFunctionBegin; 173 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 174 mat->factorerrortype = MAT_FACTOR_NOERROR; 175 mat->factorerror_zeropivot_value = 0.0; 176 mat->factorerror_zeropivot_row = 0; 177 PetscFunctionReturn(0); 178 } 179 180 PETSC_INTERN PetscErrorCode MatFindNonzeroRowsOrCols_Basic(Mat mat,PetscBool cols,PetscReal tol,IS *nonzero) 181 { 182 PetscErrorCode ierr; 183 Vec r,l; 184 const PetscScalar *al; 185 PetscInt i,nz,gnz,N,n; 186 187 PetscFunctionBegin; 188 ierr = MatCreateVecs(mat,&r,&l);CHKERRQ(ierr); 189 if (!cols) { /* nonzero rows */ 190 ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 191 ierr = MatGetLocalSize(mat,&n,NULL);CHKERRQ(ierr); 192 ierr = VecSet(l,0.0);CHKERRQ(ierr); 193 ierr = VecSetRandom(r,NULL);CHKERRQ(ierr); 194 ierr = MatMult(mat,r,l);CHKERRQ(ierr); 195 ierr = VecGetArrayRead(l,&al);CHKERRQ(ierr); 196 } else { /* nonzero columns */ 197 ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr); 198 ierr = MatGetLocalSize(mat,NULL,&n);CHKERRQ(ierr); 199 ierr = VecSet(r,0.0);CHKERRQ(ierr); 200 ierr = VecSetRandom(l,NULL);CHKERRQ(ierr); 201 ierr = MatMultTranspose(mat,l,r);CHKERRQ(ierr); 202 ierr = VecGetArrayRead(r,&al);CHKERRQ(ierr); 203 } 204 if (tol <= 0.0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nz++; } 205 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nz++; } 206 ierr = MPIU_Allreduce(&nz,&gnz,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 207 if (gnz != N) { 208 PetscInt *nzr; 209 ierr = PetscMalloc1(nz,&nzr);CHKERRQ(ierr); 210 if (nz) { 211 if (tol < 0) { for (i=0,nz=0;i<n;i++) if (al[i] != 0.0) nzr[nz++] = i; } 212 else { for (i=0,nz=0;i<n;i++) if (PetscAbsScalar(al[i]) > tol) nzr[nz++] = i; } 213 } 214 ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),nz,nzr,PETSC_OWN_POINTER,nonzero);CHKERRQ(ierr); 215 } else *nonzero = NULL; 216 if (!cols) { /* nonzero rows */ 217 ierr = VecRestoreArrayRead(l,&al);CHKERRQ(ierr); 218 } else { 219 ierr = VecRestoreArrayRead(r,&al);CHKERRQ(ierr); 220 } 221 ierr = VecDestroy(&l);CHKERRQ(ierr); 222 ierr = VecDestroy(&r);CHKERRQ(ierr); 223 PetscFunctionReturn(0); 224 } 225 226 /*@ 227 MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix 228 229 Input Parameter: 230 . A - the matrix 231 232 Output Parameter: 233 . keptrows - the rows that are not completely zero 234 235 Notes: 236 keptrows is set to NULL if all rows are nonzero. 237 238 Level: intermediate 239 240 @*/ 241 PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows) 242 { 243 PetscErrorCode ierr; 244 245 PetscFunctionBegin; 246 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 247 PetscValidType(mat,1); 248 PetscValidPointer(keptrows,2); 249 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 250 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 251 if (!mat->ops->findnonzerorows) { 252 ierr = MatFindNonzeroRowsOrCols_Basic(mat,PETSC_FALSE,0.0,keptrows);CHKERRQ(ierr); 253 } else { 254 ierr = (*mat->ops->findnonzerorows)(mat,keptrows);CHKERRQ(ierr); 255 } 256 PetscFunctionReturn(0); 257 } 258 259 /*@ 260 MatFindZeroRows - Locate all rows that are completely zero in the matrix 261 262 Input Parameter: 263 . A - the matrix 264 265 Output Parameter: 266 . zerorows - the rows that are completely zero 267 268 Notes: 269 zerorows is set to NULL if no rows are zero. 270 271 Level: intermediate 272 273 @*/ 274 PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows) 275 { 276 PetscErrorCode ierr; 277 IS keptrows; 278 PetscInt m, n; 279 280 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 281 PetscValidType(mat,1); 282 283 ierr = MatFindNonzeroRows(mat, &keptrows);CHKERRQ(ierr); 284 /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows. 285 In keeping with this convention, we set zerorows to NULL if there are no zero 286 rows. */ 287 if (keptrows == NULL) { 288 *zerorows = NULL; 289 } else { 290 ierr = MatGetOwnershipRange(mat,&m,&n);CHKERRQ(ierr); 291 ierr = ISComplement(keptrows,m,n,zerorows);CHKERRQ(ierr); 292 ierr = ISDestroy(&keptrows);CHKERRQ(ierr); 293 } 294 PetscFunctionReturn(0); 295 } 296 297 /*@ 298 MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling 299 300 Not Collective 301 302 Input Parameters: 303 . A - the matrix 304 305 Output Parameters: 306 . a - the diagonal part (which is a SEQUENTIAL matrix) 307 308 Notes: 309 see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix. 310 Use caution, as the reference count on the returned matrix is not incremented and it is used as 311 part of the containing MPI Mat's normal operation. 312 313 Level: advanced 314 315 @*/ 316 PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a) 317 { 318 PetscErrorCode ierr; 319 320 PetscFunctionBegin; 321 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 322 PetscValidType(A,1); 323 PetscValidPointer(a,3); 324 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 325 if (!A->ops->getdiagonalblock) { 326 PetscMPIInt size; 327 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);CHKERRQ(ierr); 328 if (size == 1) { 329 *a = A; 330 PetscFunctionReturn(0); 331 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type"); 332 } 333 ierr = (*A->ops->getdiagonalblock)(A,a);CHKERRQ(ierr); 334 PetscFunctionReturn(0); 335 } 336 337 /*@ 338 MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries. 339 340 Collective on Mat 341 342 Input Parameters: 343 . mat - the matrix 344 345 Output Parameter: 346 . trace - the sum of the diagonal entries 347 348 Level: advanced 349 350 @*/ 351 PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace) 352 { 353 PetscErrorCode ierr; 354 Vec diag; 355 356 PetscFunctionBegin; 357 ierr = MatCreateVecs(mat,&diag,NULL);CHKERRQ(ierr); 358 ierr = MatGetDiagonal(mat,diag);CHKERRQ(ierr); 359 ierr = VecSum(diag,trace);CHKERRQ(ierr); 360 ierr = VecDestroy(&diag);CHKERRQ(ierr); 361 PetscFunctionReturn(0); 362 } 363 364 /*@ 365 MatRealPart - Zeros out the imaginary part of the matrix 366 367 Logically Collective on Mat 368 369 Input Parameters: 370 . mat - the matrix 371 372 Level: advanced 373 374 375 .seealso: MatImaginaryPart() 376 @*/ 377 PetscErrorCode MatRealPart(Mat mat) 378 { 379 PetscErrorCode ierr; 380 381 PetscFunctionBegin; 382 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 383 PetscValidType(mat,1); 384 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 385 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 386 if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 387 MatCheckPreallocated(mat,1); 388 ierr = (*mat->ops->realpart)(mat);CHKERRQ(ierr); 389 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 390 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 391 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 392 } 393 #endif 394 PetscFunctionReturn(0); 395 } 396 397 /*@C 398 MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix 399 400 Collective on Mat 401 402 Input Parameter: 403 . mat - the matrix 404 405 Output Parameters: 406 + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block) 407 - ghosts - the global indices of the ghost points 408 409 Notes: 410 the nghosts and ghosts are suitable to pass into VecCreateGhost() 411 412 Level: advanced 413 414 @*/ 415 PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[]) 416 { 417 PetscErrorCode ierr; 418 419 PetscFunctionBegin; 420 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 421 PetscValidType(mat,1); 422 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 423 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 424 if (!mat->ops->getghosts) { 425 if (nghosts) *nghosts = 0; 426 if (ghosts) *ghosts = 0; 427 } else { 428 ierr = (*mat->ops->getghosts)(mat,nghosts,ghosts);CHKERRQ(ierr); 429 } 430 PetscFunctionReturn(0); 431 } 432 433 434 /*@ 435 MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part 436 437 Logically Collective on Mat 438 439 Input Parameters: 440 . mat - the matrix 441 442 Level: advanced 443 444 445 .seealso: MatRealPart() 446 @*/ 447 PetscErrorCode MatImaginaryPart(Mat mat) 448 { 449 PetscErrorCode ierr; 450 451 PetscFunctionBegin; 452 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 453 PetscValidType(mat,1); 454 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 455 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 456 if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 457 MatCheckPreallocated(mat,1); 458 ierr = (*mat->ops->imaginarypart)(mat);CHKERRQ(ierr); 459 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 460 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 461 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 462 } 463 #endif 464 PetscFunctionReturn(0); 465 } 466 467 /*@ 468 MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices) 469 470 Not Collective 471 472 Input Parameter: 473 . mat - the matrix 474 475 Output Parameters: 476 + missing - is any diagonal missing 477 - dd - first diagonal entry that is missing (optional) on this process 478 479 Level: advanced 480 481 482 .seealso: MatRealPart() 483 @*/ 484 PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd) 485 { 486 PetscErrorCode ierr; 487 488 PetscFunctionBegin; 489 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 490 PetscValidType(mat,1); 491 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 492 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 493 if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 494 ierr = (*mat->ops->missingdiagonal)(mat,missing,dd);CHKERRQ(ierr); 495 PetscFunctionReturn(0); 496 } 497 498 /*@C 499 MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow() 500 for each row that you get to ensure that your application does 501 not bleed memory. 502 503 Not Collective 504 505 Input Parameters: 506 + mat - the matrix 507 - row - the row to get 508 509 Output Parameters: 510 + ncols - if not NULL, the number of nonzeros in the row 511 . cols - if not NULL, the column numbers 512 - vals - if not NULL, the values 513 514 Notes: 515 This routine is provided for people who need to have direct access 516 to the structure of a matrix. We hope that we provide enough 517 high-level matrix routines that few users will need it. 518 519 MatGetRow() always returns 0-based column indices, regardless of 520 whether the internal representation is 0-based (default) or 1-based. 521 522 For better efficiency, set cols and/or vals to NULL if you do 523 not wish to extract these quantities. 524 525 The user can only examine the values extracted with MatGetRow(); 526 the values cannot be altered. To change the matrix entries, one 527 must use MatSetValues(). 528 529 You can only have one call to MatGetRow() outstanding for a particular 530 matrix at a time, per processor. MatGetRow() can only obtain rows 531 associated with the given processor, it cannot get rows from the 532 other processors; for that we suggest using MatCreateSubMatrices(), then 533 MatGetRow() on the submatrix. The row index passed to MatGetRow() 534 is in the global number of rows. 535 536 Fortran Notes: 537 The calling sequence from Fortran is 538 .vb 539 MatGetRow(matrix,row,ncols,cols,values,ierr) 540 Mat matrix (input) 541 integer row (input) 542 integer ncols (output) 543 integer cols(maxcols) (output) 544 double precision (or double complex) values(maxcols) output 545 .ve 546 where maxcols >= maximum nonzeros in any row of the matrix. 547 548 549 Caution: 550 Do not try to change the contents of the output arrays (cols and vals). 551 In some cases, this may corrupt the matrix. 552 553 Level: advanced 554 555 .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal() 556 @*/ 557 PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 558 { 559 PetscErrorCode ierr; 560 PetscInt incols; 561 562 PetscFunctionBegin; 563 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 564 PetscValidType(mat,1); 565 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 566 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 567 if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 568 MatCheckPreallocated(mat,1); 569 ierr = PetscLogEventBegin(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 570 ierr = (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);CHKERRQ(ierr); 571 if (ncols) *ncols = incols; 572 ierr = PetscLogEventEnd(MAT_GetRow,mat,0,0,0);CHKERRQ(ierr); 573 PetscFunctionReturn(0); 574 } 575 576 /*@ 577 MatConjugate - replaces the matrix values with their complex conjugates 578 579 Logically Collective on Mat 580 581 Input Parameters: 582 . mat - the matrix 583 584 Level: advanced 585 586 .seealso: VecConjugate() 587 @*/ 588 PetscErrorCode MatConjugate(Mat mat) 589 { 590 #if defined(PETSC_USE_COMPLEX) 591 PetscErrorCode ierr; 592 593 PetscFunctionBegin; 594 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 595 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 596 if (!mat->ops->conjugate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not provided for this matrix format, send email to petsc-maint@mcs.anl.gov"); 597 ierr = (*mat->ops->conjugate)(mat);CHKERRQ(ierr); 598 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 599 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 600 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 601 } 602 #endif 603 PetscFunctionReturn(0); 604 #else 605 return 0; 606 #endif 607 } 608 609 /*@C 610 MatRestoreRow - Frees any temporary space allocated by MatGetRow(). 611 612 Not Collective 613 614 Input Parameters: 615 + mat - the matrix 616 . row - the row to get 617 . ncols, cols - the number of nonzeros and their columns 618 - vals - if nonzero the column values 619 620 Notes: 621 This routine should be called after you have finished examining the entries. 622 623 This routine zeros out ncols, cols, and vals. This is to prevent accidental 624 us of the array after it has been restored. If you pass NULL, it will 625 not zero the pointers. Use of cols or vals after MatRestoreRow is invalid. 626 627 Fortran Notes: 628 The calling sequence from Fortran is 629 .vb 630 MatRestoreRow(matrix,row,ncols,cols,values,ierr) 631 Mat matrix (input) 632 integer row (input) 633 integer ncols (output) 634 integer cols(maxcols) (output) 635 double precision (or double complex) values(maxcols) output 636 .ve 637 Where maxcols >= maximum nonzeros in any row of the matrix. 638 639 In Fortran MatRestoreRow() MUST be called after MatGetRow() 640 before another call to MatGetRow() can be made. 641 642 Level: advanced 643 644 .seealso: MatGetRow() 645 @*/ 646 PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[]) 647 { 648 PetscErrorCode ierr; 649 650 PetscFunctionBegin; 651 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 652 if (ncols) PetscValidIntPointer(ncols,3); 653 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 654 if (!mat->ops->restorerow) PetscFunctionReturn(0); 655 ierr = (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);CHKERRQ(ierr); 656 if (ncols) *ncols = 0; 657 if (cols) *cols = NULL; 658 if (vals) *vals = NULL; 659 PetscFunctionReturn(0); 660 } 661 662 /*@ 663 MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format. 664 You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag. 665 666 Not Collective 667 668 Input Parameters: 669 + mat - the matrix 670 671 Notes: 672 The flag is to ensure that users are aware of MatGetRow() only provides the upper trianglular part of the row for the matrices in MATSBAIJ format. 673 674 Level: advanced 675 676 .seealso: MatRestoreRowUpperTriangular() 677 @*/ 678 PetscErrorCode MatGetRowUpperTriangular(Mat mat) 679 { 680 PetscErrorCode ierr; 681 682 PetscFunctionBegin; 683 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 684 PetscValidType(mat,1); 685 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 686 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 687 MatCheckPreallocated(mat,1); 688 if (!mat->ops->getrowuppertriangular) PetscFunctionReturn(0); 689 ierr = (*mat->ops->getrowuppertriangular)(mat);CHKERRQ(ierr); 690 PetscFunctionReturn(0); 691 } 692 693 /*@ 694 MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format. 695 696 Not Collective 697 698 Input Parameters: 699 + mat - the matrix 700 701 Notes: 702 This routine should be called after you have finished MatGetRow/MatRestoreRow(). 703 704 705 Level: advanced 706 707 .seealso: MatGetRowUpperTriangular() 708 @*/ 709 PetscErrorCode MatRestoreRowUpperTriangular(Mat mat) 710 { 711 PetscErrorCode ierr; 712 713 PetscFunctionBegin; 714 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 715 PetscValidType(mat,1); 716 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 717 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 718 MatCheckPreallocated(mat,1); 719 if (!mat->ops->restorerowuppertriangular) PetscFunctionReturn(0); 720 ierr = (*mat->ops->restorerowuppertriangular)(mat);CHKERRQ(ierr); 721 PetscFunctionReturn(0); 722 } 723 724 /*@C 725 MatSetOptionsPrefix - Sets the prefix used for searching for all 726 Mat options in the database. 727 728 Logically Collective on Mat 729 730 Input Parameter: 731 + A - the Mat context 732 - prefix - the prefix to prepend to all option names 733 734 Notes: 735 A hyphen (-) must NOT be given at the beginning of the prefix name. 736 The first character of all runtime options is AUTOMATICALLY the hyphen. 737 738 Level: advanced 739 740 .seealso: MatSetFromOptions() 741 @*/ 742 PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[]) 743 { 744 PetscErrorCode ierr; 745 746 PetscFunctionBegin; 747 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 748 ierr = PetscObjectSetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 749 PetscFunctionReturn(0); 750 } 751 752 /*@C 753 MatAppendOptionsPrefix - Appends to the prefix used for searching for all 754 Mat options in the database. 755 756 Logically Collective on Mat 757 758 Input Parameters: 759 + A - the Mat context 760 - prefix - the prefix to prepend to all option names 761 762 Notes: 763 A hyphen (-) must NOT be given at the beginning of the prefix name. 764 The first character of all runtime options is AUTOMATICALLY the hyphen. 765 766 Level: advanced 767 768 .seealso: MatGetOptionsPrefix() 769 @*/ 770 PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[]) 771 { 772 PetscErrorCode ierr; 773 774 PetscFunctionBegin; 775 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 776 ierr = PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 777 PetscFunctionReturn(0); 778 } 779 780 /*@C 781 MatGetOptionsPrefix - Sets the prefix used for searching for all 782 Mat options in the database. 783 784 Not Collective 785 786 Input Parameter: 787 . A - the Mat context 788 789 Output Parameter: 790 . prefix - pointer to the prefix string used 791 792 Notes: 793 On the fortran side, the user should pass in a string 'prefix' of 794 sufficient length to hold the prefix. 795 796 Level: advanced 797 798 .seealso: MatAppendOptionsPrefix() 799 @*/ 800 PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[]) 801 { 802 PetscErrorCode ierr; 803 804 PetscFunctionBegin; 805 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 806 ierr = PetscObjectGetOptionsPrefix((PetscObject)A,prefix);CHKERRQ(ierr); 807 PetscFunctionReturn(0); 808 } 809 810 /*@ 811 MatResetPreallocation - Reset mat to use the original nonzero pattern provided by users. 812 813 Collective on Mat 814 815 Input Parameters: 816 . A - the Mat context 817 818 Notes: 819 The allocated memory will be shrunk after calling MatAssembly with MAT_FINAL_ASSEMBLY. Users can reset the preallocation to access the original memory. 820 Currently support MPIAIJ and SEQAIJ. 821 822 Level: beginner 823 824 .seealso: MatSeqAIJSetPreallocation(), MatMPIAIJSetPreallocation(), MatXAIJSetPreallocation() 825 @*/ 826 PetscErrorCode MatResetPreallocation(Mat A) 827 { 828 PetscErrorCode ierr; 829 830 PetscFunctionBegin; 831 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 832 PetscValidType(A,1); 833 ierr = PetscUseMethod(A,"MatResetPreallocation_C",(Mat),(A));CHKERRQ(ierr); 834 PetscFunctionReturn(0); 835 } 836 837 838 /*@ 839 MatSetUp - Sets up the internal matrix data structures for the later use. 840 841 Collective on Mat 842 843 Input Parameters: 844 . A - the Mat context 845 846 Notes: 847 If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used. 848 849 If a suitable preallocation routine is used, this function does not need to be called. 850 851 See the Performance chapter of the PETSc users manual for how to preallocate matrices 852 853 Level: beginner 854 855 .seealso: MatCreate(), MatDestroy() 856 @*/ 857 PetscErrorCode MatSetUp(Mat A) 858 { 859 PetscMPIInt size; 860 PetscErrorCode ierr; 861 862 PetscFunctionBegin; 863 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 864 if (!((PetscObject)A)->type_name) { 865 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);CHKERRQ(ierr); 866 if (size == 1) { 867 ierr = MatSetType(A, MATSEQAIJ);CHKERRQ(ierr); 868 } else { 869 ierr = MatSetType(A, MATMPIAIJ);CHKERRQ(ierr); 870 } 871 } 872 if (!A->preallocated && A->ops->setup) { 873 ierr = PetscInfo(A,"Warning not preallocating matrix storage\n");CHKERRQ(ierr); 874 ierr = (*A->ops->setup)(A);CHKERRQ(ierr); 875 } 876 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 877 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 878 A->preallocated = PETSC_TRUE; 879 PetscFunctionReturn(0); 880 } 881 882 #if defined(PETSC_HAVE_SAWS) 883 #include <petscviewersaws.h> 884 #endif 885 /*@C 886 MatView - Visualizes a matrix object. 887 888 Collective on Mat 889 890 Input Parameters: 891 + mat - the matrix 892 - viewer - visualization context 893 894 Notes: 895 The available visualization contexts include 896 + PETSC_VIEWER_STDOUT_SELF - for sequential matrices 897 . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD 898 . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm 899 - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure 900 901 The user can open alternative visualization contexts with 902 + PetscViewerASCIIOpen() - Outputs matrix to a specified file 903 . PetscViewerBinaryOpen() - Outputs matrix in binary to a 904 specified file; corresponding input uses MatLoad() 905 . PetscViewerDrawOpen() - Outputs nonzero matrix structure to 906 an X window display 907 - PetscViewerSocketOpen() - Outputs matrix to Socket viewer. 908 Currently only the sequential dense and AIJ 909 matrix types support the Socket viewer. 910 911 The user can call PetscViewerPushFormat() to specify the output 912 format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF, 913 PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include 914 + PETSC_VIEWER_DEFAULT - default, prints matrix contents 915 . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format 916 . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros 917 . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse 918 format common among all matrix types 919 . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific 920 format (which is in many cases the same as the default) 921 . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix 922 size and structure (not the matrix entries) 923 - PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about 924 the matrix structure 925 926 Options Database Keys: 927 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd() 928 . -mat_view ::ascii_info_detail - Prints more detailed info 929 . -mat_view - Prints matrix in ASCII format 930 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 931 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 932 . -display <name> - Sets display name (default is host) 933 . -draw_pause <sec> - Sets number of seconds to pause after display 934 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: ch_matlab for details) 935 . -viewer_socket_machine <machine> - 936 . -viewer_socket_port <port> - 937 . -mat_view binary - save matrix to file in binary format 938 - -viewer_binary_filename <name> - 939 Level: beginner 940 941 Notes: 942 The ASCII viewers are only recommended for small matrices on at most a moderate number of processes, 943 the program will seemingly hang and take hours for larger matrices, for larger matrices one should use the binary format. 944 945 See the manual page for MatLoad() for the exact format of the binary file when the binary 946 viewer is used. 947 948 See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary 949 viewer is used. 950 951 One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure, 952 and then use the following mouse functions. 953 + left mouse: zoom in 954 . middle mouse: zoom out 955 - right mouse: continue with the simulation 956 957 .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), 958 PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad() 959 @*/ 960 PetscErrorCode MatView(Mat mat,PetscViewer viewer) 961 { 962 PetscErrorCode ierr; 963 PetscInt rows,cols,rbs,cbs; 964 PetscBool iascii,ibinary,isstring; 965 PetscViewerFormat format; 966 PetscMPIInt size; 967 #if defined(PETSC_HAVE_SAWS) 968 PetscBool issaws; 969 #endif 970 971 PetscFunctionBegin; 972 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 973 PetscValidType(mat,1); 974 if (!viewer) { 975 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);CHKERRQ(ierr); 976 } 977 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 978 PetscCheckSameComm(mat,1,viewer,2); 979 MatCheckPreallocated(mat,1); 980 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 981 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 982 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(0); 983 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 984 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 985 if (ibinary) { 986 PetscBool mpiio; 987 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);CHKERRQ(ierr); 988 if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag"); 989 } 990 991 ierr = PetscLogEventBegin(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 992 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 993 if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) { 994 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed"); 995 } 996 997 #if defined(PETSC_HAVE_SAWS) 998 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr); 999 #endif 1000 if (iascii) { 1001 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix"); 1002 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);CHKERRQ(ierr); 1003 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1004 MatNullSpace nullsp,transnullsp; 1005 1006 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1007 ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 1008 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 1009 if (rbs != 1 || cbs != 1) { 1010 if (rbs != cbs) {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);CHKERRQ(ierr);} 1011 else {ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);CHKERRQ(ierr);} 1012 } else { 1013 ierr = PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);CHKERRQ(ierr); 1014 } 1015 if (mat->factortype) { 1016 MatSolverType solver; 1017 ierr = MatFactorGetSolverType(mat,&solver);CHKERRQ(ierr); 1018 ierr = PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);CHKERRQ(ierr); 1019 } 1020 if (mat->ops->getinfo) { 1021 MatInfo info; 1022 ierr = MatGetInfo(mat,MAT_GLOBAL_SUM,&info);CHKERRQ(ierr); 1023 ierr = PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);CHKERRQ(ierr); 1024 ierr = PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);CHKERRQ(ierr); 1025 } 1026 ierr = MatGetNullSpace(mat,&nullsp);CHKERRQ(ierr); 1027 ierr = MatGetTransposeNullSpace(mat,&transnullsp);CHKERRQ(ierr); 1028 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached null space\n");CHKERRQ(ierr);} 1029 if (transnullsp && transnullsp != nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached transposed null space\n");CHKERRQ(ierr);} 1030 ierr = MatGetNearNullSpace(mat,&nullsp);CHKERRQ(ierr); 1031 if (nullsp) {ierr = PetscViewerASCIIPrintf(viewer," has attached near null space\n");CHKERRQ(ierr);} 1032 } 1033 #if defined(PETSC_HAVE_SAWS) 1034 } else if (issaws) { 1035 PetscMPIInt rank; 1036 1037 ierr = PetscObjectName((PetscObject)mat);CHKERRQ(ierr); 1038 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 1039 if (!((PetscObject)mat)->amsmem && !rank) { 1040 ierr = PetscObjectViewSAWs((PetscObject)mat,viewer);CHKERRQ(ierr); 1041 } 1042 #endif 1043 } else if (isstring) { 1044 const char *type; 1045 ierr = MatGetType(mat,&type);CHKERRQ(ierr); 1046 ierr = PetscViewerStringSPrintf(viewer," MatType: %-7.7s",type);CHKERRQ(ierr); 1047 if (mat->ops->view) {ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr);} 1048 } 1049 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && mat->ops->viewnative) { 1050 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1051 ierr = (*mat->ops->viewnative)(mat,viewer);CHKERRQ(ierr); 1052 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1053 } else if (mat->ops->view) { 1054 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 1055 ierr = (*mat->ops->view)(mat,viewer);CHKERRQ(ierr); 1056 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1057 } 1058 if (iascii) { 1059 ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1060 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 1061 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 1062 } 1063 } 1064 ierr = PetscLogEventEnd(MAT_View,mat,viewer,0,0);CHKERRQ(ierr); 1065 PetscFunctionReturn(0); 1066 } 1067 1068 #if defined(PETSC_USE_DEBUG) 1069 #include <../src/sys/totalview/tv_data_display.h> 1070 PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat) 1071 { 1072 TV_add_row("Local rows", "int", &mat->rmap->n); 1073 TV_add_row("Local columns", "int", &mat->cmap->n); 1074 TV_add_row("Global rows", "int", &mat->rmap->N); 1075 TV_add_row("Global columns", "int", &mat->cmap->N); 1076 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name); 1077 return TV_format_OK; 1078 } 1079 #endif 1080 1081 /*@C 1082 MatLoad - Loads a matrix that has been stored in binary/HDF5 format 1083 with MatView(). The matrix format is determined from the options database. 1084 Generates a parallel MPI matrix if the communicator has more than one 1085 processor. The default matrix type is AIJ. 1086 1087 Collective on PetscViewer 1088 1089 Input Parameters: 1090 + newmat - the newly loaded matrix, this needs to have been created with MatCreate() 1091 or some related function before a call to MatLoad() 1092 - viewer - binary/HDF5 file viewer 1093 1094 Options Database Keys: 1095 Used with block matrix formats (MATSEQBAIJ, ...) to specify 1096 block size 1097 . -matload_block_size <bs> 1098 1099 Level: beginner 1100 1101 Notes: 1102 If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the 1103 Mat before calling this routine if you wish to set it from the options database. 1104 1105 MatLoad() automatically loads into the options database any options 1106 given in the file filename.info where filename is the name of the file 1107 that was passed to the PetscViewerBinaryOpen(). The options in the info 1108 file will be ignored if you use the -viewer_binary_skip_info option. 1109 1110 If the type or size of newmat is not set before a call to MatLoad, PETSc 1111 sets the default matrix type AIJ and sets the local and global sizes. 1112 If type and/or size is already set, then the same are used. 1113 1114 In parallel, each processor can load a subset of rows (or the 1115 entire matrix). This routine is especially useful when a large 1116 matrix is stored on disk and only part of it is desired on each 1117 processor. For example, a parallel solver may access only some of 1118 the rows from each processor. The algorithm used here reads 1119 relatively small blocks of data rather than reading the entire 1120 matrix and then subsetting it. 1121 1122 Viewer's PetscViewerType must be either PETSCVIEWERBINARY or PETSCVIEWERHDF5. 1123 Such viewer can be created using PetscViewerBinaryOpen()/PetscViewerHDF5Open(), 1124 or the sequence like 1125 $ PetscViewer v; 1126 $ PetscViewerCreate(PETSC_COMM_WORLD,&v); 1127 $ PetscViewerSetType(v,PETSCVIEWERBINARY); 1128 $ PetscViewerSetFromOptions(v); 1129 $ PetscViewerFileSetMode(v,FILE_MODE_READ); 1130 $ PetscViewerFileSetName(v,"datafile"); 1131 The optional PetscViewerSetFromOptions() call allows to override PetscViewerSetType() using option 1132 $ -viewer_type {binary,hdf5} 1133 1134 See the example src/ksp/ksp/examples/tutorials/ex27.c with the first approach, 1135 and src/mat/examples/tutorials/ex10.c with the second approach. 1136 1137 Notes about the PETSc binary format: 1138 In case of PETSCVIEWERBINARY, a native PETSc binary format is used. Each of the blocks 1139 is read onto rank 0 and then shipped to its destination rank, one after another. 1140 Multiple objects, both matrices and vectors, can be stored within the same file. 1141 Their PetscObject name is ignored; they are loaded in the order of their storage. 1142 1143 Most users should not need to know the details of the binary storage 1144 format, since MatLoad() and MatView() completely hide these details. 1145 But for anyone who's interested, the standard binary matrix storage 1146 format is 1147 1148 $ int MAT_FILE_CLASSID 1149 $ int number of rows 1150 $ int number of columns 1151 $ int total number of nonzeros 1152 $ int *number nonzeros in each row 1153 $ int *column indices of all nonzeros (starting index is zero) 1154 $ PetscScalar *values of all nonzeros 1155 1156 PETSc automatically does the byte swapping for 1157 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 1158 linux, Windows and the paragon; thus if you write your own binary 1159 read/write routines you have to swap the bytes; see PetscBinaryRead() 1160 and PetscBinaryWrite() to see how this may be done. 1161 1162 Notes about the HDF5 (MATLAB MAT-File Version 7.3) format: 1163 In case of PETSCVIEWERHDF5, a parallel HDF5 reader is used. 1164 Each processor's chunk is loaded independently by its owning rank. 1165 Multiple objects, both matrices and vectors, can be stored within the same file. 1166 They are looked up by their PetscObject name. 1167 1168 As the MATLAB MAT-File Version 7.3 format is also a HDF5 flavor, we decided to use 1169 by default the same structure and naming of the AIJ arrays and column count 1170 within the HDF5 file. This means that a MAT file saved with -v7.3 flag, e.g. 1171 $ save example.mat A b -v7.3 1172 can be directly read by this routine (see Reference 1 for details). 1173 Note that depending on your MATLAB version, this format might be a default, 1174 otherwise you can set it as default in Preferences. 1175 1176 Unless -nocompression flag is used to save the file in MATLAB, 1177 PETSc must be configured with ZLIB package. 1178 1179 See also examples src/mat/examples/tutorials/ex10.c and src/ksp/ksp/examples/tutorials/ex27.c 1180 1181 Current HDF5 (MAT-File) limitations: 1182 This reader currently supports only real MATSEQAIJ, MATMPIAIJ, MATSEQDENSE and MATMPIDENSE matrices. 1183 1184 Corresponding MatView() is not yet implemented. 1185 1186 The loaded matrix is actually a transpose of the original one in MATLAB, 1187 unless you push PETSC_VIEWER_HDF5_MAT format (see examples above). 1188 With this format, matrix is automatically transposed by PETSc, 1189 unless the matrix is marked as SPD or symmetric 1190 (see MatSetOption(), MAT_SPD, MAT_SYMMETRIC). 1191 1192 References: 1193 1. MATLAB(R) Documentation, manual page of save(), https://www.mathworks.com/help/matlab/ref/save.html#btox10b-1-version 1194 1195 .seealso: PetscViewerBinaryOpen(), PetscViewerSetType(), MatView(), VecLoad() 1196 1197 @*/ 1198 PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer) 1199 { 1200 PetscErrorCode ierr; 1201 PetscBool flg; 1202 1203 PetscFunctionBegin; 1204 PetscValidHeaderSpecific(newmat,MAT_CLASSID,1); 1205 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1206 1207 if (!((PetscObject)newmat)->type_name) { 1208 ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 1209 } 1210 1211 flg = PETSC_FALSE; 1212 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);CHKERRQ(ierr); 1213 if (flg) { 1214 ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 1215 ierr = MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr); 1216 } 1217 flg = PETSC_FALSE; 1218 ierr = PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);CHKERRQ(ierr); 1219 if (flg) { 1220 ierr = MatSetOption(newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 1221 } 1222 1223 if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type"); 1224 ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1225 ierr = (*newmat->ops->load)(newmat,viewer);CHKERRQ(ierr); 1226 ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr); 1227 PetscFunctionReturn(0); 1228 } 1229 1230 PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant) 1231 { 1232 PetscErrorCode ierr; 1233 Mat_Redundant *redund = *redundant; 1234 PetscInt i; 1235 1236 PetscFunctionBegin; 1237 if (redund){ 1238 if (redund->matseq) { /* via MatCreateSubMatrices() */ 1239 ierr = ISDestroy(&redund->isrow);CHKERRQ(ierr); 1240 ierr = ISDestroy(&redund->iscol);CHKERRQ(ierr); 1241 ierr = MatDestroySubMatrices(1,&redund->matseq);CHKERRQ(ierr); 1242 } else { 1243 ierr = PetscFree2(redund->send_rank,redund->recv_rank);CHKERRQ(ierr); 1244 ierr = PetscFree(redund->sbuf_j);CHKERRQ(ierr); 1245 ierr = PetscFree(redund->sbuf_a);CHKERRQ(ierr); 1246 for (i=0; i<redund->nrecvs; i++) { 1247 ierr = PetscFree(redund->rbuf_j[i]);CHKERRQ(ierr); 1248 ierr = PetscFree(redund->rbuf_a[i]);CHKERRQ(ierr); 1249 } 1250 ierr = PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);CHKERRQ(ierr); 1251 } 1252 1253 if (redund->subcomm) { 1254 ierr = PetscCommDestroy(&redund->subcomm);CHKERRQ(ierr); 1255 } 1256 ierr = PetscFree(redund);CHKERRQ(ierr); 1257 } 1258 PetscFunctionReturn(0); 1259 } 1260 1261 /*@ 1262 MatDestroy - Frees space taken by a matrix. 1263 1264 Collective on Mat 1265 1266 Input Parameter: 1267 . A - the matrix 1268 1269 Level: beginner 1270 1271 @*/ 1272 PetscErrorCode MatDestroy(Mat *A) 1273 { 1274 PetscErrorCode ierr; 1275 1276 PetscFunctionBegin; 1277 if (!*A) PetscFunctionReturn(0); 1278 PetscValidHeaderSpecific(*A,MAT_CLASSID,1); 1279 if (--((PetscObject)(*A))->refct > 0) {*A = NULL; PetscFunctionReturn(0);} 1280 1281 /* if memory was published with SAWs then destroy it */ 1282 ierr = PetscObjectSAWsViewOff((PetscObject)*A);CHKERRQ(ierr); 1283 if ((*A)->ops->destroy) { 1284 ierr = (*(*A)->ops->destroy)(*A);CHKERRQ(ierr); 1285 } 1286 1287 ierr = PetscFree((*A)->defaultvectype);CHKERRQ(ierr); 1288 ierr = PetscFree((*A)->bsizes);CHKERRQ(ierr); 1289 ierr = PetscFree((*A)->solvertype);CHKERRQ(ierr); 1290 ierr = MatDestroy_Redundant(&(*A)->redundant);CHKERRQ(ierr); 1291 ierr = MatNullSpaceDestroy(&(*A)->nullsp);CHKERRQ(ierr); 1292 ierr = MatNullSpaceDestroy(&(*A)->transnullsp);CHKERRQ(ierr); 1293 ierr = MatNullSpaceDestroy(&(*A)->nearnullsp);CHKERRQ(ierr); 1294 ierr = MatDestroy(&(*A)->schur);CHKERRQ(ierr); 1295 ierr = PetscLayoutDestroy(&(*A)->rmap);CHKERRQ(ierr); 1296 ierr = PetscLayoutDestroy(&(*A)->cmap);CHKERRQ(ierr); 1297 ierr = PetscHeaderDestroy(A);CHKERRQ(ierr); 1298 PetscFunctionReturn(0); 1299 } 1300 1301 /*@C 1302 MatSetValues - Inserts or adds a block of values into a matrix. 1303 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 1304 MUST be called after all calls to MatSetValues() have been completed. 1305 1306 Not Collective 1307 1308 Input Parameters: 1309 + mat - the matrix 1310 . v - a logically two-dimensional array of values 1311 . m, idxm - the number of rows and their global indices 1312 . n, idxn - the number of columns and their global indices 1313 - addv - either ADD_VALUES or INSERT_VALUES, where 1314 ADD_VALUES adds values to any existing entries, and 1315 INSERT_VALUES replaces existing entries with new values 1316 1317 Notes: 1318 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 1319 MatSetUp() before using this routine 1320 1321 By default the values, v, are row-oriented. See MatSetOption() for other options. 1322 1323 Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES 1324 options cannot be mixed without intervening calls to the assembly 1325 routines. 1326 1327 MatSetValues() uses 0-based row and column numbers in Fortran 1328 as well as in C. 1329 1330 Negative indices may be passed in idxm and idxn, these rows and columns are 1331 simply ignored. This allows easily inserting element stiffness matrices 1332 with homogeneous Dirchlet boundary conditions that you don't want represented 1333 in the matrix. 1334 1335 Efficiency Alert: 1336 The routine MatSetValuesBlocked() may offer much better efficiency 1337 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1338 1339 Level: beginner 1340 1341 Developer Notes: 1342 This is labeled with C so does not automatically generate Fortran stubs and interfaces 1343 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 1344 1345 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1346 InsertMode, INSERT_VALUES, ADD_VALUES 1347 @*/ 1348 PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1349 { 1350 PetscErrorCode ierr; 1351 #if defined(PETSC_USE_DEBUG) 1352 PetscInt i,j; 1353 #endif 1354 1355 PetscFunctionBeginHot; 1356 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1357 PetscValidType(mat,1); 1358 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1359 PetscValidIntPointer(idxm,3); 1360 PetscValidIntPointer(idxn,5); 1361 MatCheckPreallocated(mat,1); 1362 1363 if (mat->insertmode == NOT_SET_VALUES) { 1364 mat->insertmode = addv; 1365 } 1366 #if defined(PETSC_USE_DEBUG) 1367 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1368 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1369 if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1370 1371 for (i=0; i<m; i++) { 1372 for (j=0; j<n; j++) { 1373 if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j])) 1374 #if defined(PETSC_USE_COMPLEX) 1375 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]); 1376 #else 1377 SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]); 1378 #endif 1379 } 1380 } 1381 #endif 1382 1383 if (mat->assembled) { 1384 mat->was_assembled = PETSC_TRUE; 1385 mat->assembled = PETSC_FALSE; 1386 } 1387 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1388 ierr = (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1389 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1390 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1391 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1392 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1393 } 1394 #endif 1395 PetscFunctionReturn(0); 1396 } 1397 1398 1399 /*@ 1400 MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero 1401 values into a matrix 1402 1403 Not Collective 1404 1405 Input Parameters: 1406 + mat - the matrix 1407 . row - the (block) row to set 1408 - v - a logically two-dimensional array of values 1409 1410 Notes: 1411 By the values, v, are column-oriented (for the block version) and sorted 1412 1413 All the nonzeros in the row must be provided 1414 1415 The matrix must have previously had its column indices set 1416 1417 The row must belong to this process 1418 1419 Level: intermediate 1420 1421 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1422 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping() 1423 @*/ 1424 PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[]) 1425 { 1426 PetscErrorCode ierr; 1427 PetscInt globalrow; 1428 1429 PetscFunctionBegin; 1430 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1431 PetscValidType(mat,1); 1432 PetscValidScalarPointer(v,2); 1433 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);CHKERRQ(ierr); 1434 ierr = MatSetValuesRow(mat,globalrow,v);CHKERRQ(ierr); 1435 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1436 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1437 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1438 } 1439 #endif 1440 PetscFunctionReturn(0); 1441 } 1442 1443 /*@ 1444 MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero 1445 values into a matrix 1446 1447 Not Collective 1448 1449 Input Parameters: 1450 + mat - the matrix 1451 . row - the (block) row to set 1452 - 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 1453 1454 Notes: 1455 The values, v, are column-oriented for the block version. 1456 1457 All the nonzeros in the row must be provided 1458 1459 THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used. 1460 1461 The row must belong to this process 1462 1463 Level: advanced 1464 1465 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1466 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1467 @*/ 1468 PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[]) 1469 { 1470 PetscErrorCode ierr; 1471 1472 PetscFunctionBeginHot; 1473 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1474 PetscValidType(mat,1); 1475 MatCheckPreallocated(mat,1); 1476 PetscValidScalarPointer(v,2); 1477 #if defined(PETSC_USE_DEBUG) 1478 if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values"); 1479 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1480 #endif 1481 mat->insertmode = INSERT_VALUES; 1482 1483 if (mat->assembled) { 1484 mat->was_assembled = PETSC_TRUE; 1485 mat->assembled = PETSC_FALSE; 1486 } 1487 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1488 if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1489 ierr = (*mat->ops->setvaluesrow)(mat,row,v);CHKERRQ(ierr); 1490 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1491 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1492 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1493 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1494 } 1495 #endif 1496 PetscFunctionReturn(0); 1497 } 1498 1499 /*@ 1500 MatSetValuesStencil - Inserts or adds a block of values into a matrix. 1501 Using structured grid indexing 1502 1503 Not Collective 1504 1505 Input Parameters: 1506 + mat - the matrix 1507 . m - number of rows being entered 1508 . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered 1509 . n - number of columns being entered 1510 . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered 1511 . v - a logically two-dimensional array of values 1512 - addv - either ADD_VALUES or INSERT_VALUES, where 1513 ADD_VALUES adds values to any existing entries, and 1514 INSERT_VALUES replaces existing entries with new values 1515 1516 Notes: 1517 By default the values, v, are row-oriented. See MatSetOption() for other options. 1518 1519 Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES 1520 options cannot be mixed without intervening calls to the assembly 1521 routines. 1522 1523 The grid coordinates are across the entire grid, not just the local portion 1524 1525 MatSetValuesStencil() uses 0-based row and column numbers in Fortran 1526 as well as in C. 1527 1528 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1529 1530 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1531 or call MatSetLocalToGlobalMapping() and MatSetStencil() first. 1532 1533 The columns and rows in the stencil passed in MUST be contained within the 1534 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1535 if you create a DMDA with an overlap of one grid level and on a particular process its first 1536 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1537 first i index you can use in your column and row indices in MatSetStencil() is 5. 1538 1539 In Fortran idxm and idxn should be declared as 1540 $ MatStencil idxm(4,m),idxn(4,n) 1541 and the values inserted using 1542 $ idxm(MatStencil_i,1) = i 1543 $ idxm(MatStencil_j,1) = j 1544 $ idxm(MatStencil_k,1) = k 1545 $ idxm(MatStencil_c,1) = c 1546 etc 1547 1548 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 1549 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 1550 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 1551 DM_BOUNDARY_PERIODIC boundary type. 1552 1553 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 1554 a single value per point) you can skip filling those indices. 1555 1556 Inspired by the structured grid interface to the HYPRE package 1557 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1558 1559 Efficiency Alert: 1560 The routine MatSetValuesBlockedStencil() may offer much better efficiency 1561 for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ). 1562 1563 Level: beginner 1564 1565 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1566 MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil 1567 @*/ 1568 PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1569 { 1570 PetscErrorCode ierr; 1571 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1572 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1573 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1574 1575 PetscFunctionBegin; 1576 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1577 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1578 PetscValidType(mat,1); 1579 PetscValidIntPointer(idxm,3); 1580 PetscValidIntPointer(idxn,5); 1581 1582 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1583 jdxm = buf; jdxn = buf+m; 1584 } else { 1585 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1586 jdxm = bufm; jdxn = bufn; 1587 } 1588 for (i=0; i<m; i++) { 1589 for (j=0; j<3-sdim; j++) dxm++; 1590 tmp = *dxm++ - starts[0]; 1591 for (j=0; j<dim-1; j++) { 1592 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1593 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1594 } 1595 if (mat->stencil.noc) dxm++; 1596 jdxm[i] = tmp; 1597 } 1598 for (i=0; i<n; i++) { 1599 for (j=0; j<3-sdim; j++) dxn++; 1600 tmp = *dxn++ - starts[0]; 1601 for (j=0; j<dim-1; j++) { 1602 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1603 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1604 } 1605 if (mat->stencil.noc) dxn++; 1606 jdxn[i] = tmp; 1607 } 1608 ierr = MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1609 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1610 PetscFunctionReturn(0); 1611 } 1612 1613 /*@ 1614 MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix. 1615 Using structured grid indexing 1616 1617 Not Collective 1618 1619 Input Parameters: 1620 + mat - the matrix 1621 . m - number of rows being entered 1622 . idxm - grid coordinates for matrix rows being entered 1623 . n - number of columns being entered 1624 . idxn - grid coordinates for matrix columns being entered 1625 . v - a logically two-dimensional array of values 1626 - addv - either ADD_VALUES or INSERT_VALUES, where 1627 ADD_VALUES adds values to any existing entries, and 1628 INSERT_VALUES replaces existing entries with new values 1629 1630 Notes: 1631 By default the values, v, are row-oriented and unsorted. 1632 See MatSetOption() for other options. 1633 1634 Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES 1635 options cannot be mixed without intervening calls to the assembly 1636 routines. 1637 1638 The grid coordinates are across the entire grid, not just the local portion 1639 1640 MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran 1641 as well as in C. 1642 1643 For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine 1644 1645 In order to use this routine you must either obtain the matrix with DMCreateMatrix() 1646 or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first. 1647 1648 The columns and rows in the stencil passed in MUST be contained within the 1649 ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example, 1650 if you create a DMDA with an overlap of one grid level and on a particular process its first 1651 local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the 1652 first i index you can use in your column and row indices in MatSetStencil() is 5. 1653 1654 In Fortran idxm and idxn should be declared as 1655 $ MatStencil idxm(4,m),idxn(4,n) 1656 and the values inserted using 1657 $ idxm(MatStencil_i,1) = i 1658 $ idxm(MatStencil_j,1) = j 1659 $ idxm(MatStencil_k,1) = k 1660 etc 1661 1662 Negative indices may be passed in idxm and idxn, these rows and columns are 1663 simply ignored. This allows easily inserting element stiffness matrices 1664 with homogeneous Dirchlet boundary conditions that you don't want represented 1665 in the matrix. 1666 1667 Inspired by the structured grid interface to the HYPRE package 1668 (https://computation.llnl.gov/projects/hypre-scalable-linear-solvers-multigrid-methods) 1669 1670 Level: beginner 1671 1672 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1673 MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil, 1674 MatSetBlockSize(), MatSetLocalToGlobalMapping() 1675 @*/ 1676 PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv) 1677 { 1678 PetscErrorCode ierr; 1679 PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn; 1680 PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp; 1681 PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc); 1682 1683 PetscFunctionBegin; 1684 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1685 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1686 PetscValidType(mat,1); 1687 PetscValidIntPointer(idxm,3); 1688 PetscValidIntPointer(idxn,5); 1689 PetscValidScalarPointer(v,6); 1690 1691 if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1692 jdxm = buf; jdxn = buf+m; 1693 } else { 1694 ierr = PetscMalloc2(m,&bufm,n,&bufn);CHKERRQ(ierr); 1695 jdxm = bufm; jdxn = bufn; 1696 } 1697 for (i=0; i<m; i++) { 1698 for (j=0; j<3-sdim; j++) dxm++; 1699 tmp = *dxm++ - starts[0]; 1700 for (j=0; j<sdim-1; j++) { 1701 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1702 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 1703 } 1704 dxm++; 1705 jdxm[i] = tmp; 1706 } 1707 for (i=0; i<n; i++) { 1708 for (j=0; j<3-sdim; j++) dxn++; 1709 tmp = *dxn++ - starts[0]; 1710 for (j=0; j<sdim-1; j++) { 1711 if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1; 1712 else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1]; 1713 } 1714 dxn++; 1715 jdxn[i] = tmp; 1716 } 1717 ierr = MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);CHKERRQ(ierr); 1718 ierr = PetscFree2(bufm,bufn);CHKERRQ(ierr); 1719 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1720 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1721 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1722 } 1723 #endif 1724 PetscFunctionReturn(0); 1725 } 1726 1727 /*@ 1728 MatSetStencil - Sets the grid information for setting values into a matrix via 1729 MatSetValuesStencil() 1730 1731 Not Collective 1732 1733 Input Parameters: 1734 + mat - the matrix 1735 . dim - dimension of the grid 1, 2, or 3 1736 . dims - number of grid points in x, y, and z direction, including ghost points on your processor 1737 . starts - starting point of ghost nodes on your processor in x, y, and z direction 1738 - dof - number of degrees of freedom per node 1739 1740 1741 Inspired by the structured grid interface to the HYPRE package 1742 (www.llnl.gov/CASC/hyper) 1743 1744 For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the 1745 user. 1746 1747 Level: beginner 1748 1749 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal() 1750 MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil() 1751 @*/ 1752 PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof) 1753 { 1754 PetscInt i; 1755 1756 PetscFunctionBegin; 1757 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1758 PetscValidIntPointer(dims,3); 1759 PetscValidIntPointer(starts,4); 1760 1761 mat->stencil.dim = dim + (dof > 1); 1762 for (i=0; i<dim; i++) { 1763 mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */ 1764 mat->stencil.starts[i] = starts[dim-i-1]; 1765 } 1766 mat->stencil.dims[dim] = dof; 1767 mat->stencil.starts[dim] = 0; 1768 mat->stencil.noc = (PetscBool)(dof == 1); 1769 PetscFunctionReturn(0); 1770 } 1771 1772 /*@C 1773 MatSetValuesBlocked - Inserts or adds a block of values into a matrix. 1774 1775 Not Collective 1776 1777 Input Parameters: 1778 + mat - the matrix 1779 . v - a logically two-dimensional array of values 1780 . m, idxm - the number of block rows and their global block indices 1781 . n, idxn - the number of block columns and their global block indices 1782 - addv - either ADD_VALUES or INSERT_VALUES, where 1783 ADD_VALUES adds values to any existing entries, and 1784 INSERT_VALUES replaces existing entries with new values 1785 1786 Notes: 1787 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call 1788 MatXXXXSetPreallocation() or MatSetUp() before using this routine. 1789 1790 The m and n count the NUMBER of blocks in the row direction and column direction, 1791 NOT the total number of rows/columns; for example, if the block size is 2 and 1792 you are passing in values for rows 2,3,4,5 then m would be 2 (not 4). 1793 The values in idxm would be 1 2; that is the first index for each block divided by 1794 the block size. 1795 1796 Note that you must call MatSetBlockSize() when constructing this matrix (before 1797 preallocating it). 1798 1799 By default the values, v, are row-oriented, so the layout of 1800 v is the same as for MatSetValues(). See MatSetOption() for other options. 1801 1802 Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES 1803 options cannot be mixed without intervening calls to the assembly 1804 routines. 1805 1806 MatSetValuesBlocked() uses 0-based row and column numbers in Fortran 1807 as well as in C. 1808 1809 Negative indices may be passed in idxm and idxn, these rows and columns are 1810 simply ignored. This allows easily inserting element stiffness matrices 1811 with homogeneous Dirchlet boundary conditions that you don't want represented 1812 in the matrix. 1813 1814 Each time an entry is set within a sparse matrix via MatSetValues(), 1815 internal searching must be done to determine where to place the 1816 data in the matrix storage space. By instead inserting blocks of 1817 entries via MatSetValuesBlocked(), the overhead of matrix assembly is 1818 reduced. 1819 1820 Example: 1821 $ Suppose m=n=2 and block size(bs) = 2 The array is 1822 $ 1823 $ 1 2 | 3 4 1824 $ 5 6 | 7 8 1825 $ - - - | - - - 1826 $ 9 10 | 11 12 1827 $ 13 14 | 15 16 1828 $ 1829 $ v[] should be passed in like 1830 $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 1831 $ 1832 $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then 1833 $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16] 1834 1835 Level: intermediate 1836 1837 .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal() 1838 @*/ 1839 PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv) 1840 { 1841 PetscErrorCode ierr; 1842 1843 PetscFunctionBeginHot; 1844 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1845 PetscValidType(mat,1); 1846 if (!m || !n) PetscFunctionReturn(0); /* no values to insert */ 1847 PetscValidIntPointer(idxm,3); 1848 PetscValidIntPointer(idxn,5); 1849 PetscValidScalarPointer(v,6); 1850 MatCheckPreallocated(mat,1); 1851 if (mat->insertmode == NOT_SET_VALUES) { 1852 mat->insertmode = addv; 1853 } 1854 #if defined(PETSC_USE_DEBUG) 1855 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 1856 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1857 if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1858 #endif 1859 1860 if (mat->assembled) { 1861 mat->was_assembled = PETSC_TRUE; 1862 mat->assembled = PETSC_FALSE; 1863 } 1864 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1865 if (mat->ops->setvaluesblocked) { 1866 ierr = (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);CHKERRQ(ierr); 1867 } else { 1868 PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn; 1869 PetscInt i,j,bs,cbs; 1870 ierr = MatGetBlockSizes(mat,&bs,&cbs);CHKERRQ(ierr); 1871 if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 1872 iidxm = buf; iidxn = buf + m*bs; 1873 } else { 1874 ierr = PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);CHKERRQ(ierr); 1875 iidxm = bufr; iidxn = bufc; 1876 } 1877 for (i=0; i<m; i++) { 1878 for (j=0; j<bs; j++) { 1879 iidxm[i*bs+j] = bs*idxm[i] + j; 1880 } 1881 } 1882 for (i=0; i<n; i++) { 1883 for (j=0; j<cbs; j++) { 1884 iidxn[i*cbs+j] = cbs*idxn[i] + j; 1885 } 1886 } 1887 ierr = MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);CHKERRQ(ierr); 1888 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 1889 } 1890 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 1891 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 1892 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 1893 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 1894 } 1895 #endif 1896 PetscFunctionReturn(0); 1897 } 1898 1899 /*@ 1900 MatGetValues - Gets a block of values from a matrix. 1901 1902 Not Collective; currently only returns a local block 1903 1904 Input Parameters: 1905 + mat - the matrix 1906 . v - a logically two-dimensional array for storing the values 1907 . m, idxm - the number of rows and their global indices 1908 - n, idxn - the number of columns and their global indices 1909 1910 Notes: 1911 The user must allocate space (m*n PetscScalars) for the values, v. 1912 The values, v, are then returned in a row-oriented format, 1913 analogous to that used by default in MatSetValues(). 1914 1915 MatGetValues() uses 0-based row and column numbers in 1916 Fortran as well as in C. 1917 1918 MatGetValues() requires that the matrix has been assembled 1919 with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to 1920 MatSetValues() and MatGetValues() CANNOT be made in succession 1921 without intermediate matrix assembly. 1922 1923 Negative row or column indices will be ignored and those locations in v[] will be 1924 left unchanged. 1925 1926 Level: advanced 1927 1928 .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues() 1929 @*/ 1930 PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[]) 1931 { 1932 PetscErrorCode ierr; 1933 1934 PetscFunctionBegin; 1935 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1936 PetscValidType(mat,1); 1937 if (!m || !n) PetscFunctionReturn(0); 1938 PetscValidIntPointer(idxm,3); 1939 PetscValidIntPointer(idxn,5); 1940 PetscValidScalarPointer(v,6); 1941 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 1942 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1943 if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 1944 MatCheckPreallocated(mat,1); 1945 1946 ierr = PetscLogEventBegin(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1947 ierr = (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);CHKERRQ(ierr); 1948 ierr = PetscLogEventEnd(MAT_GetValues,mat,0,0,0);CHKERRQ(ierr); 1949 PetscFunctionReturn(0); 1950 } 1951 1952 /*@ 1953 MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and 1954 the same size. Currently, this can only be called once and creates the given matrix. 1955 1956 Not Collective 1957 1958 Input Parameters: 1959 + mat - the matrix 1960 . nb - the number of blocks 1961 . bs - the number of rows (and columns) in each block 1962 . rows - a concatenation of the rows for each block 1963 - v - a concatenation of logically two-dimensional arrays of values 1964 1965 Notes: 1966 In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix. 1967 1968 Level: advanced 1969 1970 .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(), 1971 InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues() 1972 @*/ 1973 PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[]) 1974 { 1975 PetscErrorCode ierr; 1976 1977 PetscFunctionBegin; 1978 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 1979 PetscValidType(mat,1); 1980 PetscValidScalarPointer(rows,4); 1981 PetscValidScalarPointer(v,5); 1982 #if defined(PETSC_USE_DEBUG) 1983 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 1984 #endif 1985 1986 ierr = PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1987 if (mat->ops->setvaluesbatch) { 1988 ierr = (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);CHKERRQ(ierr); 1989 } else { 1990 PetscInt b; 1991 for (b = 0; b < nb; ++b) { 1992 ierr = MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);CHKERRQ(ierr); 1993 } 1994 } 1995 ierr = PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);CHKERRQ(ierr); 1996 PetscFunctionReturn(0); 1997 } 1998 1999 /*@ 2000 MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by 2001 the routine MatSetValuesLocal() to allow users to insert matrix entries 2002 using a local (per-processor) numbering. 2003 2004 Not Collective 2005 2006 Input Parameters: 2007 + x - the matrix 2008 . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS() 2009 - cmapping - column mapping 2010 2011 Level: intermediate 2012 2013 2014 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal() 2015 @*/ 2016 PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping) 2017 { 2018 PetscErrorCode ierr; 2019 2020 PetscFunctionBegin; 2021 PetscValidHeaderSpecific(x,MAT_CLASSID,1); 2022 PetscValidType(x,1); 2023 PetscValidHeaderSpecific(rmapping,IS_LTOGM_CLASSID,2); 2024 PetscValidHeaderSpecific(cmapping,IS_LTOGM_CLASSID,3); 2025 2026 if (x->ops->setlocaltoglobalmapping) { 2027 ierr = (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);CHKERRQ(ierr); 2028 } else { 2029 ierr = PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);CHKERRQ(ierr); 2030 ierr = PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);CHKERRQ(ierr); 2031 } 2032 PetscFunctionReturn(0); 2033 } 2034 2035 2036 /*@ 2037 MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping() 2038 2039 Not Collective 2040 2041 Input Parameters: 2042 . A - the matrix 2043 2044 Output Parameters: 2045 + rmapping - row mapping 2046 - cmapping - column mapping 2047 2048 Level: advanced 2049 2050 2051 .seealso: MatSetValuesLocal() 2052 @*/ 2053 PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping) 2054 { 2055 PetscFunctionBegin; 2056 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2057 PetscValidType(A,1); 2058 if (rmapping) PetscValidPointer(rmapping,2); 2059 if (cmapping) PetscValidPointer(cmapping,3); 2060 if (rmapping) *rmapping = A->rmap->mapping; 2061 if (cmapping) *cmapping = A->cmap->mapping; 2062 PetscFunctionReturn(0); 2063 } 2064 2065 /*@ 2066 MatGetLayouts - Gets the PetscLayout objects for rows and columns 2067 2068 Not Collective 2069 2070 Input Parameters: 2071 . A - the matrix 2072 2073 Output Parameters: 2074 + rmap - row layout 2075 - cmap - column layout 2076 2077 Level: advanced 2078 2079 .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping() 2080 @*/ 2081 PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap) 2082 { 2083 PetscFunctionBegin; 2084 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2085 PetscValidType(A,1); 2086 if (rmap) PetscValidPointer(rmap,2); 2087 if (cmap) PetscValidPointer(cmap,3); 2088 if (rmap) *rmap = A->rmap; 2089 if (cmap) *cmap = A->cmap; 2090 PetscFunctionReturn(0); 2091 } 2092 2093 /*@C 2094 MatSetValuesLocal - Inserts or adds values into certain locations of a matrix, 2095 using a local ordering of the nodes. 2096 2097 Not Collective 2098 2099 Input Parameters: 2100 + mat - the matrix 2101 . nrow, irow - number of rows and their local indices 2102 . ncol, icol - number of columns and their local indices 2103 . y - a logically two-dimensional array of values 2104 - addv - either INSERT_VALUES or ADD_VALUES, where 2105 ADD_VALUES adds values to any existing entries, and 2106 INSERT_VALUES replaces existing entries with new values 2107 2108 Notes: 2109 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2110 MatSetUp() before using this routine 2111 2112 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine 2113 2114 Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES 2115 options cannot be mixed without intervening calls to the assembly 2116 routines. 2117 2118 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2119 MUST be called after all calls to MatSetValuesLocal() have been completed. 2120 2121 Level: intermediate 2122 2123 Developer Notes: 2124 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2125 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2126 2127 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(), 2128 MatSetValueLocal() 2129 @*/ 2130 PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2131 { 2132 PetscErrorCode ierr; 2133 2134 PetscFunctionBeginHot; 2135 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2136 PetscValidType(mat,1); 2137 MatCheckPreallocated(mat,1); 2138 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2139 PetscValidIntPointer(irow,3); 2140 PetscValidIntPointer(icol,5); 2141 if (mat->insertmode == NOT_SET_VALUES) { 2142 mat->insertmode = addv; 2143 } 2144 #if defined(PETSC_USE_DEBUG) 2145 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2146 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2147 if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2148 #endif 2149 2150 if (mat->assembled) { 2151 mat->was_assembled = PETSC_TRUE; 2152 mat->assembled = PETSC_FALSE; 2153 } 2154 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2155 if (mat->ops->setvalueslocal) { 2156 ierr = (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2157 } else { 2158 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2159 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2160 irowm = buf; icolm = buf+nrow; 2161 } else { 2162 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2163 irowm = bufr; icolm = bufc; 2164 } 2165 ierr = ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2166 ierr = ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2167 ierr = MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2168 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2169 } 2170 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2171 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2172 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2173 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2174 } 2175 #endif 2176 PetscFunctionReturn(0); 2177 } 2178 2179 /*@C 2180 MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix, 2181 using a local ordering of the nodes a block at a time. 2182 2183 Not Collective 2184 2185 Input Parameters: 2186 + x - the matrix 2187 . nrow, irow - number of rows and their local indices 2188 . ncol, icol - number of columns and their local indices 2189 . y - a logically two-dimensional array of values 2190 - addv - either INSERT_VALUES or ADD_VALUES, where 2191 ADD_VALUES adds values to any existing entries, and 2192 INSERT_VALUES replaces existing entries with new values 2193 2194 Notes: 2195 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or 2196 MatSetUp() before using this routine 2197 2198 If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping() 2199 before using this routineBefore calling MatSetValuesLocal(), the user must first set the 2200 2201 Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES 2202 options cannot be mixed without intervening calls to the assembly 2203 routines. 2204 2205 These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd() 2206 MUST be called after all calls to MatSetValuesBlockedLocal() have been completed. 2207 2208 Level: intermediate 2209 2210 Developer Notes: 2211 This is labeled with C so does not automatically generate Fortran stubs and interfaces 2212 because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays. 2213 2214 .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(), 2215 MatSetValuesLocal(), MatSetValuesBlocked() 2216 @*/ 2217 PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv) 2218 { 2219 PetscErrorCode ierr; 2220 2221 PetscFunctionBeginHot; 2222 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2223 PetscValidType(mat,1); 2224 MatCheckPreallocated(mat,1); 2225 if (!nrow || !ncol) PetscFunctionReturn(0); /* no values to insert */ 2226 PetscValidIntPointer(irow,3); 2227 PetscValidIntPointer(icol,5); 2228 PetscValidScalarPointer(y,6); 2229 if (mat->insertmode == NOT_SET_VALUES) { 2230 mat->insertmode = addv; 2231 } 2232 #if defined(PETSC_USE_DEBUG) 2233 else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values"); 2234 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2235 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); 2236 #endif 2237 2238 if (mat->assembled) { 2239 mat->was_assembled = PETSC_TRUE; 2240 mat->assembled = PETSC_FALSE; 2241 } 2242 #if defined(PETSC_USE_DEBUG) 2243 /* Condition on the mapping existing, because MatSetValuesBlockedLocal_IS does not require it to be set. */ 2244 if (mat->rmap->mapping) { 2245 PetscInt irbs, rbs; 2246 ierr = MatGetBlockSizes(mat, &rbs, NULL);CHKERRQ(ierr); 2247 ierr = ISLocalToGlobalMappingGetBlockSize(mat->rmap->mapping,&irbs);CHKERRQ(ierr); 2248 if (rbs != irbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different row block sizes! mat %D, row l2g map %D",rbs,irbs); 2249 } 2250 if (mat->cmap->mapping) { 2251 PetscInt icbs, cbs; 2252 ierr = MatGetBlockSizes(mat,NULL,&cbs);CHKERRQ(ierr); 2253 ierr = ISLocalToGlobalMappingGetBlockSize(mat->cmap->mapping,&icbs);CHKERRQ(ierr); 2254 if (cbs != icbs) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Different col block sizes! mat %D, col l2g map %D",cbs,icbs); 2255 } 2256 #endif 2257 ierr = PetscLogEventBegin(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2258 if (mat->ops->setvaluesblockedlocal) { 2259 ierr = (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);CHKERRQ(ierr); 2260 } else { 2261 PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm; 2262 if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) { 2263 irowm = buf; icolm = buf + nrow; 2264 } else { 2265 ierr = PetscMalloc2(nrow,&bufr,ncol,&bufc);CHKERRQ(ierr); 2266 irowm = bufr; icolm = bufc; 2267 } 2268 ierr = ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);CHKERRQ(ierr); 2269 ierr = ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);CHKERRQ(ierr); 2270 ierr = MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);CHKERRQ(ierr); 2271 ierr = PetscFree2(bufr,bufc);CHKERRQ(ierr); 2272 } 2273 ierr = PetscLogEventEnd(MAT_SetValues,mat,0,0,0);CHKERRQ(ierr); 2274 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 2275 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 2276 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 2277 } 2278 #endif 2279 PetscFunctionReturn(0); 2280 } 2281 2282 /*@ 2283 MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal 2284 2285 Collective on Mat 2286 2287 Input Parameters: 2288 + mat - the matrix 2289 - x - the vector to be multiplied 2290 2291 Output Parameters: 2292 . y - the result 2293 2294 Notes: 2295 The vectors x and y cannot be the same. I.e., one cannot 2296 call MatMult(A,y,y). 2297 2298 Level: developer 2299 2300 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2301 @*/ 2302 PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y) 2303 { 2304 PetscErrorCode ierr; 2305 2306 PetscFunctionBegin; 2307 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2308 PetscValidType(mat,1); 2309 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2310 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2311 2312 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2313 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2314 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2315 MatCheckPreallocated(mat,1); 2316 2317 if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2318 ierr = (*mat->ops->multdiagonalblock)(mat,x,y);CHKERRQ(ierr); 2319 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2320 PetscFunctionReturn(0); 2321 } 2322 2323 /* --------------------------------------------------------*/ 2324 /*@ 2325 MatMult - Computes the matrix-vector product, y = Ax. 2326 2327 Neighbor-wise Collective on Mat 2328 2329 Input Parameters: 2330 + mat - the matrix 2331 - x - the vector to be multiplied 2332 2333 Output Parameters: 2334 . y - the result 2335 2336 Notes: 2337 The vectors x and y cannot be the same. I.e., one cannot 2338 call MatMult(A,y,y). 2339 2340 Level: beginner 2341 2342 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2343 @*/ 2344 PetscErrorCode MatMult(Mat mat,Vec x,Vec y) 2345 { 2346 PetscErrorCode ierr; 2347 2348 PetscFunctionBegin; 2349 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2350 PetscValidType(mat,1); 2351 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2352 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2353 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2354 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2355 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2356 #if !defined(PETSC_HAVE_CONSTRAINTS) 2357 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); 2358 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); 2359 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); 2360 #endif 2361 ierr = VecSetErrorIfLocked(y,3);CHKERRQ(ierr); 2362 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2363 MatCheckPreallocated(mat,1); 2364 2365 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2366 if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined"); 2367 ierr = PetscLogEventBegin(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2368 ierr = (*mat->ops->mult)(mat,x,y);CHKERRQ(ierr); 2369 ierr = PetscLogEventEnd(MAT_Mult,mat,x,y,0);CHKERRQ(ierr); 2370 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2371 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2372 PetscFunctionReturn(0); 2373 } 2374 2375 /*@ 2376 MatMultTranspose - Computes matrix transpose times a vector y = A^T * x. 2377 2378 Neighbor-wise Collective on Mat 2379 2380 Input Parameters: 2381 + mat - the matrix 2382 - x - the vector to be multiplied 2383 2384 Output Parameters: 2385 . y - the result 2386 2387 Notes: 2388 The vectors x and y cannot be the same. I.e., one cannot 2389 call MatMultTranspose(A,y,y). 2390 2391 For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple, 2392 use MatMultHermitianTranspose() 2393 2394 Level: beginner 2395 2396 .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose() 2397 @*/ 2398 PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y) 2399 { 2400 PetscErrorCode ierr; 2401 2402 PetscFunctionBegin; 2403 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2404 PetscValidType(mat,1); 2405 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2406 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2407 2408 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2409 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2410 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2411 #if !defined(PETSC_HAVE_CONSTRAINTS) 2412 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); 2413 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); 2414 #endif 2415 if (mat->erroriffailure) {ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);} 2416 MatCheckPreallocated(mat,1); 2417 2418 if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply transpose defined"); 2419 ierr = PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2420 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2421 ierr = (*mat->ops->multtranspose)(mat,x,y);CHKERRQ(ierr); 2422 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2423 ierr = PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);CHKERRQ(ierr); 2424 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2425 if (mat->erroriffailure) {ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);} 2426 PetscFunctionReturn(0); 2427 } 2428 2429 /*@ 2430 MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector. 2431 2432 Neighbor-wise Collective on Mat 2433 2434 Input Parameters: 2435 + mat - the matrix 2436 - x - the vector to be multilplied 2437 2438 Output Parameters: 2439 . y - the result 2440 2441 Notes: 2442 The vectors x and y cannot be the same. I.e., one cannot 2443 call MatMultHermitianTranspose(A,y,y). 2444 2445 Also called the conjugate transpose, complex conjugate transpose, or adjoint. 2446 2447 For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical. 2448 2449 Level: beginner 2450 2451 .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose() 2452 @*/ 2453 PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y) 2454 { 2455 PetscErrorCode ierr; 2456 Vec w; 2457 2458 PetscFunctionBegin; 2459 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2460 PetscValidType(mat,1); 2461 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2462 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2463 2464 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2465 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2466 if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2467 #if !defined(PETSC_HAVE_CONSTRAINTS) 2468 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); 2469 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); 2470 #endif 2471 MatCheckPreallocated(mat,1); 2472 2473 ierr = PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2474 if (mat->ops->multhermitiantranspose) { 2475 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2476 ierr = (*mat->ops->multhermitiantranspose)(mat,x,y);CHKERRQ(ierr); 2477 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2478 } else { 2479 ierr = VecDuplicate(x,&w);CHKERRQ(ierr); 2480 ierr = VecCopy(x,w);CHKERRQ(ierr); 2481 ierr = VecConjugate(w);CHKERRQ(ierr); 2482 ierr = MatMultTranspose(mat,w,y);CHKERRQ(ierr); 2483 ierr = VecDestroy(&w);CHKERRQ(ierr); 2484 ierr = VecConjugate(y);CHKERRQ(ierr); 2485 } 2486 ierr = PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);CHKERRQ(ierr); 2487 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2488 PetscFunctionReturn(0); 2489 } 2490 2491 /*@ 2492 MatMultAdd - Computes v3 = v2 + A * v1. 2493 2494 Neighbor-wise Collective on Mat 2495 2496 Input Parameters: 2497 + mat - the matrix 2498 - v1, v2 - the vectors 2499 2500 Output Parameters: 2501 . v3 - the result 2502 2503 Notes: 2504 The vectors v1 and v3 cannot be the same. I.e., one cannot 2505 call MatMultAdd(A,v1,v2,v1). 2506 2507 Level: beginner 2508 2509 .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd() 2510 @*/ 2511 PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2512 { 2513 PetscErrorCode ierr; 2514 2515 PetscFunctionBegin; 2516 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2517 PetscValidType(mat,1); 2518 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2519 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2520 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2521 2522 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2523 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2524 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); 2525 /* 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); 2526 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); */ 2527 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); 2528 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); 2529 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2530 MatCheckPreallocated(mat,1); 2531 2532 if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name); 2533 ierr = PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2534 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2535 ierr = (*mat->ops->multadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2536 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2537 ierr = PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2538 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2539 PetscFunctionReturn(0); 2540 } 2541 2542 /*@ 2543 MatMultTransposeAdd - Computes v3 = v2 + A' * v1. 2544 2545 Neighbor-wise Collective on Mat 2546 2547 Input Parameters: 2548 + mat - the matrix 2549 - v1, v2 - the vectors 2550 2551 Output Parameters: 2552 . v3 - the result 2553 2554 Notes: 2555 The vectors v1 and v3 cannot be the same. I.e., one cannot 2556 call MatMultTransposeAdd(A,v1,v2,v1). 2557 2558 Level: beginner 2559 2560 .seealso: MatMultTranspose(), MatMultAdd(), MatMult() 2561 @*/ 2562 PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2563 { 2564 PetscErrorCode ierr; 2565 2566 PetscFunctionBegin; 2567 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2568 PetscValidType(mat,1); 2569 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2570 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2571 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2572 2573 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2574 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2575 if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2576 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2577 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); 2578 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); 2579 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); 2580 MatCheckPreallocated(mat,1); 2581 2582 ierr = PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2583 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2584 ierr = (*mat->ops->multtransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2585 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2586 ierr = PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2587 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2588 PetscFunctionReturn(0); 2589 } 2590 2591 /*@ 2592 MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1. 2593 2594 Neighbor-wise Collective on Mat 2595 2596 Input Parameters: 2597 + mat - the matrix 2598 - v1, v2 - the vectors 2599 2600 Output Parameters: 2601 . v3 - the result 2602 2603 Notes: 2604 The vectors v1 and v3 cannot be the same. I.e., one cannot 2605 call MatMultHermitianTransposeAdd(A,v1,v2,v1). 2606 2607 Level: beginner 2608 2609 .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult() 2610 @*/ 2611 PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3) 2612 { 2613 PetscErrorCode ierr; 2614 2615 PetscFunctionBegin; 2616 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2617 PetscValidType(mat,1); 2618 PetscValidHeaderSpecific(v1,VEC_CLASSID,2); 2619 PetscValidHeaderSpecific(v2,VEC_CLASSID,3); 2620 PetscValidHeaderSpecific(v3,VEC_CLASSID,4); 2621 2622 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2623 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2624 if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors"); 2625 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); 2626 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); 2627 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); 2628 MatCheckPreallocated(mat,1); 2629 2630 ierr = PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2631 ierr = VecLockReadPush(v1);CHKERRQ(ierr); 2632 if (mat->ops->multhermitiantransposeadd) { 2633 ierr = (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);CHKERRQ(ierr); 2634 } else { 2635 Vec w,z; 2636 ierr = VecDuplicate(v1,&w);CHKERRQ(ierr); 2637 ierr = VecCopy(v1,w);CHKERRQ(ierr); 2638 ierr = VecConjugate(w);CHKERRQ(ierr); 2639 ierr = VecDuplicate(v3,&z);CHKERRQ(ierr); 2640 ierr = MatMultTranspose(mat,w,z);CHKERRQ(ierr); 2641 ierr = VecDestroy(&w);CHKERRQ(ierr); 2642 ierr = VecConjugate(z);CHKERRQ(ierr); 2643 if (v2 != v3) { 2644 ierr = VecWAXPY(v3,1.0,v2,z);CHKERRQ(ierr); 2645 } else { 2646 ierr = VecAXPY(v3,1.0,z);CHKERRQ(ierr); 2647 } 2648 ierr = VecDestroy(&z);CHKERRQ(ierr); 2649 } 2650 ierr = VecLockReadPop(v1);CHKERRQ(ierr); 2651 ierr = PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);CHKERRQ(ierr); 2652 ierr = PetscObjectStateIncrease((PetscObject)v3);CHKERRQ(ierr); 2653 PetscFunctionReturn(0); 2654 } 2655 2656 /*@ 2657 MatMultConstrained - The inner multiplication routine for a 2658 constrained matrix P^T A P. 2659 2660 Neighbor-wise Collective on Mat 2661 2662 Input Parameters: 2663 + mat - the matrix 2664 - x - the vector to be multilplied 2665 2666 Output Parameters: 2667 . y - the result 2668 2669 Notes: 2670 The vectors x and y cannot be the same. I.e., one cannot 2671 call MatMult(A,y,y). 2672 2673 Level: beginner 2674 2675 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2676 @*/ 2677 PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y) 2678 { 2679 PetscErrorCode ierr; 2680 2681 PetscFunctionBegin; 2682 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2683 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2684 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2685 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2686 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2687 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2688 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); 2689 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); 2690 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); 2691 2692 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2693 ierr = VecLockReadPush(x);CHKERRQ(ierr); 2694 ierr = (*mat->ops->multconstrained)(mat,x,y);CHKERRQ(ierr); 2695 ierr = VecLockReadPop(x);CHKERRQ(ierr); 2696 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2697 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2698 PetscFunctionReturn(0); 2699 } 2700 2701 /*@ 2702 MatMultTransposeConstrained - The inner multiplication routine for a 2703 constrained matrix P^T A^T P. 2704 2705 Neighbor-wise Collective on Mat 2706 2707 Input Parameters: 2708 + mat - the matrix 2709 - x - the vector to be multilplied 2710 2711 Output Parameters: 2712 . y - the result 2713 2714 Notes: 2715 The vectors x and y cannot be the same. I.e., one cannot 2716 call MatMult(A,y,y). 2717 2718 Level: beginner 2719 2720 .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 2721 @*/ 2722 PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y) 2723 { 2724 PetscErrorCode ierr; 2725 2726 PetscFunctionBegin; 2727 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2728 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2729 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2730 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2731 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2732 if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors"); 2733 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); 2734 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); 2735 2736 ierr = PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2737 ierr = (*mat->ops->multtransposeconstrained)(mat,x,y);CHKERRQ(ierr); 2738 ierr = PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);CHKERRQ(ierr); 2739 ierr = PetscObjectStateIncrease((PetscObject)y);CHKERRQ(ierr); 2740 PetscFunctionReturn(0); 2741 } 2742 2743 /*@C 2744 MatGetFactorType - gets the type of factorization it is 2745 2746 Not Collective 2747 2748 Input Parameters: 2749 . mat - the matrix 2750 2751 Output Parameters: 2752 . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2753 2754 Level: intermediate 2755 2756 .seealso: MatFactorType, MatGetFactor(), MatSetFactorType() 2757 @*/ 2758 PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t) 2759 { 2760 PetscFunctionBegin; 2761 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2762 PetscValidType(mat,1); 2763 PetscValidPointer(t,2); 2764 *t = mat->factortype; 2765 PetscFunctionReturn(0); 2766 } 2767 2768 /*@C 2769 MatSetFactorType - sets the type of factorization it is 2770 2771 Logically Collective on Mat 2772 2773 Input Parameters: 2774 + mat - the matrix 2775 - t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT 2776 2777 Level: intermediate 2778 2779 .seealso: MatFactorType, MatGetFactor(), MatGetFactorType() 2780 @*/ 2781 PetscErrorCode MatSetFactorType(Mat mat, MatFactorType t) 2782 { 2783 PetscFunctionBegin; 2784 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2785 PetscValidType(mat,1); 2786 mat->factortype = t; 2787 PetscFunctionReturn(0); 2788 } 2789 2790 /* ------------------------------------------------------------*/ 2791 /*@C 2792 MatGetInfo - Returns information about matrix storage (number of 2793 nonzeros, memory, etc.). 2794 2795 Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag 2796 2797 Input Parameters: 2798 . mat - the matrix 2799 2800 Output Parameters: 2801 + flag - flag indicating the type of parameters to be returned 2802 (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors, 2803 MAT_GLOBAL_SUM - sum over all processors) 2804 - info - matrix information context 2805 2806 Notes: 2807 The MatInfo context contains a variety of matrix data, including 2808 number of nonzeros allocated and used, number of mallocs during 2809 matrix assembly, etc. Additional information for factored matrices 2810 is provided (such as the fill ratio, number of mallocs during 2811 factorization, etc.). Much of this info is printed to PETSC_STDOUT 2812 when using the runtime options 2813 $ -info -mat_view ::ascii_info 2814 2815 Example for C/C++ Users: 2816 See the file ${PETSC_DIR}/include/petscmat.h for a complete list of 2817 data within the MatInfo context. For example, 2818 .vb 2819 MatInfo info; 2820 Mat A; 2821 double mal, nz_a, nz_u; 2822 2823 MatGetInfo(A,MAT_LOCAL,&info); 2824 mal = info.mallocs; 2825 nz_a = info.nz_allocated; 2826 .ve 2827 2828 Example for Fortran Users: 2829 Fortran users should declare info as a double precision 2830 array of dimension MAT_INFO_SIZE, and then extract the parameters 2831 of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h 2832 a complete list of parameter names. 2833 .vb 2834 double precision info(MAT_INFO_SIZE) 2835 double precision mal, nz_a 2836 Mat A 2837 integer ierr 2838 2839 call MatGetInfo(A,MAT_LOCAL,info,ierr) 2840 mal = info(MAT_INFO_MALLOCS) 2841 nz_a = info(MAT_INFO_NZ_ALLOCATED) 2842 .ve 2843 2844 Level: intermediate 2845 2846 Developer Note: fortran interface is not autogenerated as the f90 2847 interface defintion cannot be generated correctly [due to MatInfo] 2848 2849 .seealso: MatStashGetInfo() 2850 2851 @*/ 2852 PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info) 2853 { 2854 PetscErrorCode ierr; 2855 2856 PetscFunctionBegin; 2857 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2858 PetscValidType(mat,1); 2859 PetscValidPointer(info,3); 2860 if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2861 MatCheckPreallocated(mat,1); 2862 ierr = (*mat->ops->getinfo)(mat,flag,info);CHKERRQ(ierr); 2863 PetscFunctionReturn(0); 2864 } 2865 2866 /* 2867 This is used by external packages where it is not easy to get the info from the actual 2868 matrix factorization. 2869 */ 2870 PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info) 2871 { 2872 PetscErrorCode ierr; 2873 2874 PetscFunctionBegin; 2875 ierr = PetscMemzero(info,sizeof(MatInfo));CHKERRQ(ierr); 2876 PetscFunctionReturn(0); 2877 } 2878 2879 /* ----------------------------------------------------------*/ 2880 2881 /*@C 2882 MatLUFactor - Performs in-place LU factorization of matrix. 2883 2884 Collective on Mat 2885 2886 Input Parameters: 2887 + mat - the matrix 2888 . row - row permutation 2889 . col - column permutation 2890 - info - options for factorization, includes 2891 $ fill - expected fill as ratio of original fill. 2892 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 2893 $ Run with the option -info to determine an optimal value to use 2894 2895 Notes: 2896 Most users should employ the simplified KSP interface for linear solvers 2897 instead of working directly with matrix algebra routines such as this. 2898 See, e.g., KSPCreate(). 2899 2900 This changes the state of the matrix to a factored matrix; it cannot be used 2901 for example with MatSetValues() unless one first calls MatSetUnfactored(). 2902 2903 Level: developer 2904 2905 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), 2906 MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor() 2907 2908 Developer Note: fortran interface is not autogenerated as the f90 2909 interface defintion cannot be generated correctly [due to MatFactorInfo] 2910 2911 @*/ 2912 PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2913 { 2914 PetscErrorCode ierr; 2915 MatFactorInfo tinfo; 2916 2917 PetscFunctionBegin; 2918 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2919 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2920 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2921 if (info) PetscValidPointer(info,4); 2922 PetscValidType(mat,1); 2923 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2924 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2925 if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2926 MatCheckPreallocated(mat,1); 2927 if (!info) { 2928 ierr = MatFactorInfoInitialize(&tinfo);CHKERRQ(ierr); 2929 info = &tinfo; 2930 } 2931 2932 ierr = PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2933 ierr = (*mat->ops->lufactor)(mat,row,col,info);CHKERRQ(ierr); 2934 ierr = PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);CHKERRQ(ierr); 2935 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2936 PetscFunctionReturn(0); 2937 } 2938 2939 /*@C 2940 MatILUFactor - Performs in-place ILU factorization of matrix. 2941 2942 Collective on Mat 2943 2944 Input Parameters: 2945 + mat - the matrix 2946 . row - row permutation 2947 . col - column permutation 2948 - info - structure containing 2949 $ levels - number of levels of fill. 2950 $ expected fill - as ratio of original fill. 2951 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 2952 missing diagonal entries) 2953 2954 Notes: 2955 Probably really in-place only when level of fill is zero, otherwise allocates 2956 new space to store factored matrix and deletes previous memory. 2957 2958 Most users should employ the simplified KSP interface for linear solvers 2959 instead of working directly with matrix algebra routines such as this. 2960 See, e.g., KSPCreate(). 2961 2962 Level: developer 2963 2964 .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 2965 2966 Developer Note: fortran interface is not autogenerated as the f90 2967 interface defintion cannot be generated correctly [due to MatFactorInfo] 2968 2969 @*/ 2970 PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info) 2971 { 2972 PetscErrorCode ierr; 2973 2974 PetscFunctionBegin; 2975 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 2976 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 2977 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 2978 PetscValidPointer(info,4); 2979 PetscValidType(mat,1); 2980 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 2981 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 2982 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2983 if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 2984 MatCheckPreallocated(mat,1); 2985 2986 ierr = PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2987 ierr = (*mat->ops->ilufactor)(mat,row,col,info);CHKERRQ(ierr); 2988 ierr = PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);CHKERRQ(ierr); 2989 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 2990 PetscFunctionReturn(0); 2991 } 2992 2993 /*@C 2994 MatLUFactorSymbolic - Performs symbolic LU factorization of matrix. 2995 Call this routine before calling MatLUFactorNumeric(). 2996 2997 Collective on Mat 2998 2999 Input Parameters: 3000 + fact - the factor matrix obtained with MatGetFactor() 3001 . mat - the matrix 3002 . row, col - row and column permutations 3003 - info - options for factorization, includes 3004 $ fill - expected fill as ratio of original fill. 3005 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3006 $ Run with the option -info to determine an optimal value to use 3007 3008 3009 Notes: 3010 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 3011 3012 Most users should employ the simplified KSP interface for linear solvers 3013 instead of working directly with matrix algebra routines such as this. 3014 See, e.g., KSPCreate(). 3015 3016 Level: developer 3017 3018 .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize() 3019 3020 Developer Note: fortran interface is not autogenerated as the f90 3021 interface defintion cannot be generated correctly [due to MatFactorInfo] 3022 3023 @*/ 3024 PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 3025 { 3026 PetscErrorCode ierr; 3027 3028 PetscFunctionBegin; 3029 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3030 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 3031 if (col) PetscValidHeaderSpecific(col,IS_CLASSID,3); 3032 if (info) PetscValidPointer(info,4); 3033 PetscValidType(mat,1); 3034 PetscValidPointer(fact,5); 3035 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3036 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3037 if (!(fact)->ops->lufactorsymbolic) { 3038 MatSolverType spackage; 3039 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3040 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage); 3041 } 3042 MatCheckPreallocated(mat,2); 3043 3044 ierr = PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3045 ierr = (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 3046 ierr = PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 3047 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3048 PetscFunctionReturn(0); 3049 } 3050 3051 /*@C 3052 MatLUFactorNumeric - Performs numeric LU factorization of a matrix. 3053 Call this routine after first calling MatLUFactorSymbolic(). 3054 3055 Collective on Mat 3056 3057 Input Parameters: 3058 + fact - the factor matrix obtained with MatGetFactor() 3059 . mat - the matrix 3060 - info - options for factorization 3061 3062 Notes: 3063 See MatLUFactor() for in-place factorization. See 3064 MatCholeskyFactorNumeric() for the symmetric, positive definite case. 3065 3066 Most users should employ the simplified KSP interface for linear solvers 3067 instead of working directly with matrix algebra routines such as this. 3068 See, e.g., KSPCreate(). 3069 3070 Level: developer 3071 3072 .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor() 3073 3074 Developer Note: fortran interface is not autogenerated as the f90 3075 interface defintion cannot be generated correctly [due to MatFactorInfo] 3076 3077 @*/ 3078 PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3079 { 3080 PetscErrorCode ierr; 3081 3082 PetscFunctionBegin; 3083 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3084 PetscValidType(mat,1); 3085 PetscValidPointer(fact,2); 3086 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3087 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3088 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); 3089 3090 if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name); 3091 MatCheckPreallocated(mat,2); 3092 ierr = PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3093 ierr = (fact->ops->lufactornumeric)(fact,mat,info);CHKERRQ(ierr); 3094 ierr = PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3095 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3096 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3097 PetscFunctionReturn(0); 3098 } 3099 3100 /*@C 3101 MatCholeskyFactor - Performs in-place Cholesky factorization of a 3102 symmetric matrix. 3103 3104 Collective on Mat 3105 3106 Input Parameters: 3107 + mat - the matrix 3108 . perm - row and column permutations 3109 - f - expected fill as ratio of original fill 3110 3111 Notes: 3112 See MatLUFactor() for the nonsymmetric case. See also 3113 MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric(). 3114 3115 Most users should employ the simplified KSP interface for linear solvers 3116 instead of working directly with matrix algebra routines such as this. 3117 See, e.g., KSPCreate(). 3118 3119 Level: developer 3120 3121 .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric() 3122 MatGetOrdering() 3123 3124 Developer Note: fortran interface is not autogenerated as the f90 3125 interface defintion cannot be generated correctly [due to MatFactorInfo] 3126 3127 @*/ 3128 PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info) 3129 { 3130 PetscErrorCode ierr; 3131 3132 PetscFunctionBegin; 3133 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3134 PetscValidType(mat,1); 3135 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3136 if (info) PetscValidPointer(info,3); 3137 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3138 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3139 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3140 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); 3141 MatCheckPreallocated(mat,1); 3142 3143 ierr = PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3144 ierr = (*mat->ops->choleskyfactor)(mat,perm,info);CHKERRQ(ierr); 3145 ierr = PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);CHKERRQ(ierr); 3146 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 3147 PetscFunctionReturn(0); 3148 } 3149 3150 /*@C 3151 MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization 3152 of a symmetric matrix. 3153 3154 Collective on Mat 3155 3156 Input Parameters: 3157 + fact - the factor matrix obtained with MatGetFactor() 3158 . mat - the matrix 3159 . perm - row and column permutations 3160 - info - options for factorization, includes 3161 $ fill - expected fill as ratio of original fill. 3162 $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting) 3163 $ Run with the option -info to determine an optimal value to use 3164 3165 Notes: 3166 See MatLUFactorSymbolic() for the nonsymmetric case. See also 3167 MatCholeskyFactor() and MatCholeskyFactorNumeric(). 3168 3169 Most users should employ the simplified KSP interface for linear solvers 3170 instead of working directly with matrix algebra routines such as this. 3171 See, e.g., KSPCreate(). 3172 3173 Level: developer 3174 3175 .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric() 3176 MatGetOrdering() 3177 3178 Developer Note: fortran interface is not autogenerated as the f90 3179 interface defintion cannot be generated correctly [due to MatFactorInfo] 3180 3181 @*/ 3182 PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 3183 { 3184 PetscErrorCode ierr; 3185 3186 PetscFunctionBegin; 3187 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3188 PetscValidType(mat,1); 3189 if (perm) PetscValidHeaderSpecific(perm,IS_CLASSID,2); 3190 if (info) PetscValidPointer(info,3); 3191 PetscValidPointer(fact,4); 3192 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square"); 3193 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3194 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3195 if (!(fact)->ops->choleskyfactorsymbolic) { 3196 MatSolverType spackage; 3197 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 3198 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage); 3199 } 3200 MatCheckPreallocated(mat,2); 3201 3202 ierr = PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3203 ierr = (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 3204 ierr = PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 3205 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3206 PetscFunctionReturn(0); 3207 } 3208 3209 /*@C 3210 MatCholeskyFactorNumeric - Performs numeric Cholesky factorization 3211 of a symmetric matrix. Call this routine after first calling 3212 MatCholeskyFactorSymbolic(). 3213 3214 Collective on Mat 3215 3216 Input Parameters: 3217 + fact - the factor matrix obtained with MatGetFactor() 3218 . mat - the initial matrix 3219 . info - options for factorization 3220 - fact - the symbolic factor of mat 3221 3222 3223 Notes: 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: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric() 3231 3232 Developer Note: fortran interface is not autogenerated as the f90 3233 interface defintion cannot be generated correctly [due to MatFactorInfo] 3234 3235 @*/ 3236 PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info) 3237 { 3238 PetscErrorCode ierr; 3239 3240 PetscFunctionBegin; 3241 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3242 PetscValidType(mat,1); 3243 PetscValidPointer(fact,2); 3244 PetscValidHeaderSpecific(fact,MAT_CLASSID,2); 3245 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3246 if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name); 3247 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); 3248 MatCheckPreallocated(mat,2); 3249 3250 ierr = PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3251 ierr = (fact->ops->choleskyfactornumeric)(fact,mat,info);CHKERRQ(ierr); 3252 ierr = PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);CHKERRQ(ierr); 3253 ierr = MatViewFromOptions(fact,NULL,"-mat_factor_view");CHKERRQ(ierr); 3254 ierr = PetscObjectStateIncrease((PetscObject)fact);CHKERRQ(ierr); 3255 PetscFunctionReturn(0); 3256 } 3257 3258 /* ----------------------------------------------------------------*/ 3259 /*@ 3260 MatSolve - Solves A x = b, given a factored matrix. 3261 3262 Neighbor-wise Collective on Mat 3263 3264 Input Parameters: 3265 + mat - the factored matrix 3266 - b - the right-hand-side vector 3267 3268 Output Parameter: 3269 . x - the result vector 3270 3271 Notes: 3272 The vectors b and x cannot be the same. I.e., one cannot 3273 call MatSolve(A,x,x). 3274 3275 Notes: 3276 Most users should employ the simplified KSP interface for linear solvers 3277 instead of working directly with matrix algebra routines such as this. 3278 See, e.g., KSPCreate(). 3279 3280 Level: developer 3281 3282 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd() 3283 @*/ 3284 PetscErrorCode MatSolve(Mat mat,Vec b,Vec x) 3285 { 3286 PetscErrorCode ierr; 3287 3288 PetscFunctionBegin; 3289 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3290 PetscValidType(mat,1); 3291 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3292 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3293 PetscCheckSameComm(mat,1,b,2); 3294 PetscCheckSameComm(mat,1,x,3); 3295 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3296 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); 3297 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); 3298 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); 3299 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3300 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3301 MatCheckPreallocated(mat,1); 3302 3303 ierr = PetscLogEventBegin(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3304 if (mat->factorerrortype) { 3305 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3306 ierr = VecSetInf(x);CHKERRQ(ierr); 3307 } else { 3308 if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3309 ierr = (*mat->ops->solve)(mat,b,x);CHKERRQ(ierr); 3310 } 3311 ierr = PetscLogEventEnd(MAT_Solve,mat,b,x,0);CHKERRQ(ierr); 3312 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3313 PetscFunctionReturn(0); 3314 } 3315 3316 static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans) 3317 { 3318 PetscErrorCode ierr; 3319 Vec b,x; 3320 PetscInt m,N,i; 3321 PetscScalar *bb,*xx; 3322 PetscBool flg; 3323 3324 PetscFunctionBegin; 3325 ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 3326 if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix"); 3327 ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 3328 if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix"); 3329 3330 ierr = MatDenseGetArray(B,&bb);CHKERRQ(ierr); 3331 ierr = MatDenseGetArray(X,&xx);CHKERRQ(ierr); 3332 ierr = MatGetLocalSize(B,&m,NULL);CHKERRQ(ierr); /* number local rows */ 3333 ierr = MatGetSize(B,NULL,&N);CHKERRQ(ierr); /* total columns in dense matrix */ 3334 ierr = MatCreateVecs(A,&x,&b);CHKERRQ(ierr); 3335 for (i=0; i<N; i++) { 3336 ierr = VecPlaceArray(b,bb + i*m);CHKERRQ(ierr); 3337 ierr = VecPlaceArray(x,xx + i*m);CHKERRQ(ierr); 3338 if (trans) { 3339 ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr); 3340 } else { 3341 ierr = MatSolve(A,b,x);CHKERRQ(ierr); 3342 } 3343 ierr = VecResetArray(x);CHKERRQ(ierr); 3344 ierr = VecResetArray(b);CHKERRQ(ierr); 3345 } 3346 ierr = VecDestroy(&b);CHKERRQ(ierr); 3347 ierr = VecDestroy(&x);CHKERRQ(ierr); 3348 ierr = MatDenseRestoreArray(B,&bb);CHKERRQ(ierr); 3349 ierr = MatDenseRestoreArray(X,&xx);CHKERRQ(ierr); 3350 PetscFunctionReturn(0); 3351 } 3352 3353 /*@ 3354 MatMatSolve - Solves A X = B, given a factored matrix. 3355 3356 Neighbor-wise Collective on Mat 3357 3358 Input Parameters: 3359 + A - the factored matrix 3360 - B - the right-hand-side matrix (dense matrix) 3361 3362 Output Parameter: 3363 . X - the result matrix (dense matrix) 3364 3365 Notes: 3366 The matrices b and x cannot be the same. I.e., one cannot 3367 call MatMatSolve(A,x,x). 3368 3369 Notes: 3370 Most users should usually employ the simplified KSP interface for linear solvers 3371 instead of working directly with matrix algebra routines such as this. 3372 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3373 at a time. 3374 3375 When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS 3376 it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides. 3377 3378 Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B. 3379 3380 Level: developer 3381 3382 .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3383 @*/ 3384 PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X) 3385 { 3386 PetscErrorCode ierr; 3387 3388 PetscFunctionBegin; 3389 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3390 PetscValidType(A,1); 3391 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3392 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3393 PetscCheckSameComm(A,1,B,2); 3394 PetscCheckSameComm(A,1,X,3); 3395 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3396 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); 3397 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); 3398 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"); 3399 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3400 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3401 MatCheckPreallocated(A,1); 3402 3403 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3404 if (!A->ops->matsolve) { 3405 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3406 ierr = MatMatSolve_Basic(A,B,X,PETSC_FALSE);CHKERRQ(ierr); 3407 } else { 3408 ierr = (*A->ops->matsolve)(A,B,X);CHKERRQ(ierr); 3409 } 3410 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3411 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3412 PetscFunctionReturn(0); 3413 } 3414 3415 /*@ 3416 MatMatSolveTranspose - Solves A^T X = B, given a factored matrix. 3417 3418 Neighbor-wise Collective on Mat 3419 3420 Input Parameters: 3421 + A - the factored matrix 3422 - B - the right-hand-side matrix (dense matrix) 3423 3424 Output Parameter: 3425 . X - the result matrix (dense matrix) 3426 3427 Notes: 3428 The matrices B and X cannot be the same. I.e., one cannot 3429 call MatMatSolveTranspose(A,X,X). 3430 3431 Notes: 3432 Most users should usually employ the simplified KSP interface for linear solvers 3433 instead of working directly with matrix algebra routines such as this. 3434 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3435 at a time. 3436 3437 When using SuperLU_Dist or MUMPS as a parallel solver, PETSc will use their functionality to solve multiple right hand sides simultaneously. 3438 3439 Level: developer 3440 3441 .seealso: MatMatSolve(), MatLUFactor(), MatCholeskyFactor() 3442 @*/ 3443 PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X) 3444 { 3445 PetscErrorCode ierr; 3446 3447 PetscFunctionBegin; 3448 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3449 PetscValidType(A,1); 3450 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 3451 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3452 PetscCheckSameComm(A,1,B,2); 3453 PetscCheckSameComm(A,1,X,3); 3454 if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3455 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); 3456 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); 3457 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); 3458 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"); 3459 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3460 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3461 MatCheckPreallocated(A,1); 3462 3463 ierr = PetscLogEventBegin(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3464 if (!A->ops->matsolvetranspose) { 3465 ierr = PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);CHKERRQ(ierr); 3466 ierr = MatMatSolve_Basic(A,B,X,PETSC_TRUE);CHKERRQ(ierr); 3467 } else { 3468 ierr = (*A->ops->matsolvetranspose)(A,B,X);CHKERRQ(ierr); 3469 } 3470 ierr = PetscLogEventEnd(MAT_MatSolve,A,B,X,0);CHKERRQ(ierr); 3471 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3472 PetscFunctionReturn(0); 3473 } 3474 3475 /*@ 3476 MatMatTransposeSolve - Solves A X = B^T, given a factored matrix. 3477 3478 Neighbor-wise Collective on Mat 3479 3480 Input Parameters: 3481 + A - the factored matrix 3482 - Bt - the transpose of right-hand-side matrix 3483 3484 Output Parameter: 3485 . X - the result matrix (dense matrix) 3486 3487 Notes: 3488 Most users should usually employ the simplified KSP interface for linear solvers 3489 instead of working directly with matrix algebra routines such as this. 3490 See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X) 3491 at a time. 3492 3493 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(). 3494 3495 Level: developer 3496 3497 .seealso: MatMatSolve(), MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor() 3498 @*/ 3499 PetscErrorCode MatMatTransposeSolve(Mat A,Mat Bt,Mat X) 3500 { 3501 PetscErrorCode ierr; 3502 3503 PetscFunctionBegin; 3504 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3505 PetscValidType(A,1); 3506 PetscValidHeaderSpecific(Bt,MAT_CLASSID,2); 3507 PetscValidHeaderSpecific(X,MAT_CLASSID,3); 3508 PetscCheckSameComm(A,1,Bt,2); 3509 PetscCheckSameComm(A,1,X,3); 3510 3511 if (X == Bt) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices"); 3512 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); 3513 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); 3514 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"); 3515 if (!A->rmap->N && !A->cmap->N) PetscFunctionReturn(0); 3516 if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3517 MatCheckPreallocated(A,1); 3518 3519 if (!A->ops->mattransposesolve) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 3520 ierr = PetscLogEventBegin(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3521 ierr = (*A->ops->mattransposesolve)(A,Bt,X);CHKERRQ(ierr); 3522 ierr = PetscLogEventEnd(MAT_MatTrSolve,A,Bt,X,0);CHKERRQ(ierr); 3523 ierr = PetscObjectStateIncrease((PetscObject)X);CHKERRQ(ierr); 3524 PetscFunctionReturn(0); 3525 } 3526 3527 /*@ 3528 MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or 3529 U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U, 3530 3531 Neighbor-wise Collective on Mat 3532 3533 Input Parameters: 3534 + mat - the factored matrix 3535 - b - the right-hand-side vector 3536 3537 Output Parameter: 3538 . x - the result vector 3539 3540 Notes: 3541 MatSolve() should be used for most applications, as it performs 3542 a forward solve followed by a backward solve. 3543 3544 The vectors b and x cannot be the same, i.e., one cannot 3545 call MatForwardSolve(A,x,x). 3546 3547 For matrix in seqsbaij format with block size larger than 1, 3548 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3549 MatForwardSolve() solves U^T*D y = b, and 3550 MatBackwardSolve() solves U x = y. 3551 Thus they do not provide a symmetric preconditioner. 3552 3553 Most users should employ the simplified KSP interface for linear solvers 3554 instead of working directly with matrix algebra routines such as this. 3555 See, e.g., KSPCreate(). 3556 3557 Level: developer 3558 3559 .seealso: MatSolve(), MatBackwardSolve() 3560 @*/ 3561 PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x) 3562 { 3563 PetscErrorCode ierr; 3564 3565 PetscFunctionBegin; 3566 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3567 PetscValidType(mat,1); 3568 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3569 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3570 PetscCheckSameComm(mat,1,b,2); 3571 PetscCheckSameComm(mat,1,x,3); 3572 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3573 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); 3574 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); 3575 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); 3576 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3577 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3578 MatCheckPreallocated(mat,1); 3579 3580 if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3581 ierr = PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3582 ierr = (*mat->ops->forwardsolve)(mat,b,x);CHKERRQ(ierr); 3583 ierr = PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);CHKERRQ(ierr); 3584 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3585 PetscFunctionReturn(0); 3586 } 3587 3588 /*@ 3589 MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU. 3590 D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U, 3591 3592 Neighbor-wise Collective on Mat 3593 3594 Input Parameters: 3595 + mat - the factored matrix 3596 - b - the right-hand-side vector 3597 3598 Output Parameter: 3599 . x - the result vector 3600 3601 Notes: 3602 MatSolve() should be used for most applications, as it performs 3603 a forward solve followed by a backward solve. 3604 3605 The vectors b and x cannot be the same. I.e., one cannot 3606 call MatBackwardSolve(A,x,x). 3607 3608 For matrix in seqsbaij format with block size larger than 1, 3609 the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet. 3610 MatForwardSolve() solves U^T*D y = b, and 3611 MatBackwardSolve() solves U x = y. 3612 Thus they do not provide a symmetric preconditioner. 3613 3614 Most users should employ the simplified KSP interface for linear solvers 3615 instead of working directly with matrix algebra routines such as this. 3616 See, e.g., KSPCreate(). 3617 3618 Level: developer 3619 3620 .seealso: MatSolve(), MatForwardSolve() 3621 @*/ 3622 PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x) 3623 { 3624 PetscErrorCode ierr; 3625 3626 PetscFunctionBegin; 3627 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3628 PetscValidType(mat,1); 3629 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3630 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3631 PetscCheckSameComm(mat,1,b,2); 3632 PetscCheckSameComm(mat,1,x,3); 3633 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3634 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); 3635 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); 3636 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); 3637 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3638 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3639 MatCheckPreallocated(mat,1); 3640 3641 if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3642 ierr = PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3643 ierr = (*mat->ops->backwardsolve)(mat,b,x);CHKERRQ(ierr); 3644 ierr = PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);CHKERRQ(ierr); 3645 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3646 PetscFunctionReturn(0); 3647 } 3648 3649 /*@ 3650 MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix. 3651 3652 Neighbor-wise Collective on Mat 3653 3654 Input Parameters: 3655 + mat - the factored matrix 3656 . b - the right-hand-side vector 3657 - y - the vector to be added to 3658 3659 Output Parameter: 3660 . x - the result vector 3661 3662 Notes: 3663 The vectors b and x cannot be the same. I.e., one cannot 3664 call MatSolveAdd(A,x,y,x). 3665 3666 Most users should employ the simplified KSP interface for linear solvers 3667 instead of working directly with matrix algebra routines such as this. 3668 See, e.g., KSPCreate(). 3669 3670 Level: developer 3671 3672 .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd() 3673 @*/ 3674 PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x) 3675 { 3676 PetscScalar one = 1.0; 3677 Vec tmp; 3678 PetscErrorCode ierr; 3679 3680 PetscFunctionBegin; 3681 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3682 PetscValidType(mat,1); 3683 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3684 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3685 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3686 PetscCheckSameComm(mat,1,b,2); 3687 PetscCheckSameComm(mat,1,y,2); 3688 PetscCheckSameComm(mat,1,x,3); 3689 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3690 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); 3691 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); 3692 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); 3693 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); 3694 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); 3695 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3696 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3697 MatCheckPreallocated(mat,1); 3698 3699 ierr = PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3700 if (mat->ops->solveadd) { 3701 ierr = (*mat->ops->solveadd)(mat,b,y,x);CHKERRQ(ierr); 3702 } else { 3703 /* do the solve then the add manually */ 3704 if (x != y) { 3705 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3706 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3707 } else { 3708 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3709 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3710 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3711 ierr = MatSolve(mat,b,x);CHKERRQ(ierr); 3712 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3713 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3714 } 3715 } 3716 ierr = PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);CHKERRQ(ierr); 3717 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3718 PetscFunctionReturn(0); 3719 } 3720 3721 /*@ 3722 MatSolveTranspose - Solves A' x = b, given a factored matrix. 3723 3724 Neighbor-wise Collective on Mat 3725 3726 Input Parameters: 3727 + mat - the factored matrix 3728 - b - the right-hand-side vector 3729 3730 Output Parameter: 3731 . x - the result vector 3732 3733 Notes: 3734 The vectors b and x cannot be the same. I.e., one cannot 3735 call MatSolveTranspose(A,x,x). 3736 3737 Most users should employ the simplified KSP interface for linear solvers 3738 instead of working directly with matrix algebra routines such as this. 3739 See, e.g., KSPCreate(). 3740 3741 Level: developer 3742 3743 .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd() 3744 @*/ 3745 PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x) 3746 { 3747 PetscErrorCode ierr; 3748 3749 PetscFunctionBegin; 3750 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3751 PetscValidType(mat,1); 3752 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3753 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 3754 PetscCheckSameComm(mat,1,b,2); 3755 PetscCheckSameComm(mat,1,x,3); 3756 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3757 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); 3758 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); 3759 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3760 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3761 MatCheckPreallocated(mat,1); 3762 ierr = PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3763 if (mat->factorerrortype) { 3764 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3765 ierr = VecSetInf(x);CHKERRQ(ierr); 3766 } else { 3767 if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name); 3768 ierr = (*mat->ops->solvetranspose)(mat,b,x);CHKERRQ(ierr); 3769 } 3770 ierr = PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);CHKERRQ(ierr); 3771 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3772 PetscFunctionReturn(0); 3773 } 3774 3775 /*@ 3776 MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a 3777 factored matrix. 3778 3779 Neighbor-wise Collective on Mat 3780 3781 Input Parameters: 3782 + mat - the factored matrix 3783 . b - the right-hand-side vector 3784 - y - the vector to be added to 3785 3786 Output Parameter: 3787 . x - the result vector 3788 3789 Notes: 3790 The vectors b and x cannot be the same. I.e., one cannot 3791 call MatSolveTransposeAdd(A,x,y,x). 3792 3793 Most users should employ the simplified KSP interface for linear solvers 3794 instead of working directly with matrix algebra routines such as this. 3795 See, e.g., KSPCreate(). 3796 3797 Level: developer 3798 3799 .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose() 3800 @*/ 3801 PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x) 3802 { 3803 PetscScalar one = 1.0; 3804 PetscErrorCode ierr; 3805 Vec tmp; 3806 3807 PetscFunctionBegin; 3808 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3809 PetscValidType(mat,1); 3810 PetscValidHeaderSpecific(y,VEC_CLASSID,2); 3811 PetscValidHeaderSpecific(b,VEC_CLASSID,3); 3812 PetscValidHeaderSpecific(x,VEC_CLASSID,4); 3813 PetscCheckSameComm(mat,1,b,2); 3814 PetscCheckSameComm(mat,1,y,3); 3815 PetscCheckSameComm(mat,1,x,4); 3816 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 3817 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); 3818 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); 3819 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); 3820 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); 3821 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 3822 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 3823 MatCheckPreallocated(mat,1); 3824 3825 ierr = PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3826 if (mat->ops->solvetransposeadd) { 3827 if (mat->factorerrortype) { 3828 ierr = PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);CHKERRQ(ierr); 3829 ierr = VecSetInf(x);CHKERRQ(ierr); 3830 } else { 3831 ierr = (*mat->ops->solvetransposeadd)(mat,b,y,x);CHKERRQ(ierr); 3832 } 3833 } else { 3834 /* do the solve then the add manually */ 3835 if (x != y) { 3836 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3837 ierr = VecAXPY(x,one,y);CHKERRQ(ierr); 3838 } else { 3839 ierr = VecDuplicate(x,&tmp);CHKERRQ(ierr); 3840 ierr = PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);CHKERRQ(ierr); 3841 ierr = VecCopy(x,tmp);CHKERRQ(ierr); 3842 ierr = MatSolveTranspose(mat,b,x);CHKERRQ(ierr); 3843 ierr = VecAXPY(x,one,tmp);CHKERRQ(ierr); 3844 ierr = VecDestroy(&tmp);CHKERRQ(ierr); 3845 } 3846 } 3847 ierr = PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);CHKERRQ(ierr); 3848 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3849 PetscFunctionReturn(0); 3850 } 3851 /* ----------------------------------------------------------------*/ 3852 3853 /*@ 3854 MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps. 3855 3856 Neighbor-wise Collective on Mat 3857 3858 Input Parameters: 3859 + mat - the matrix 3860 . b - the right hand side 3861 . omega - the relaxation factor 3862 . flag - flag indicating the type of SOR (see below) 3863 . shift - diagonal shift 3864 . its - the number of iterations 3865 - lits - the number of local iterations 3866 3867 Output Parameters: 3868 . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess) 3869 3870 SOR Flags: 3871 . SOR_FORWARD_SWEEP - forward SOR 3872 . SOR_BACKWARD_SWEEP - backward SOR 3873 . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR) 3874 . SOR_LOCAL_FORWARD_SWEEP - local forward SOR 3875 . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR 3876 . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR 3877 . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies 3878 upper/lower triangular part of matrix to 3879 vector (with omega) 3880 . SOR_ZERO_INITIAL_GUESS - zero initial guess 3881 3882 Notes: 3883 SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and 3884 SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings 3885 on each processor. 3886 3887 Application programmers will not generally use MatSOR() directly, 3888 but instead will employ the KSP/PC interface. 3889 3890 Notes: 3891 for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing 3892 3893 Notes for Advanced Users: 3894 The flags are implemented as bitwise inclusive or operations. 3895 For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP) 3896 to specify a zero initial guess for SSOR. 3897 3898 Most users should employ the simplified KSP interface for linear solvers 3899 instead of working directly with matrix algebra routines such as this. 3900 See, e.g., KSPCreate(). 3901 3902 Vectors x and b CANNOT be the same 3903 3904 Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes 3905 3906 Level: developer 3907 3908 @*/ 3909 PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x) 3910 { 3911 PetscErrorCode ierr; 3912 3913 PetscFunctionBegin; 3914 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3915 PetscValidType(mat,1); 3916 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 3917 PetscValidHeaderSpecific(x,VEC_CLASSID,8); 3918 PetscCheckSameComm(mat,1,b,2); 3919 PetscCheckSameComm(mat,1,x,8); 3920 if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 3921 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3922 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3923 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); 3924 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); 3925 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); 3926 if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its); 3927 if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits); 3928 if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same"); 3929 3930 MatCheckPreallocated(mat,1); 3931 ierr = PetscLogEventBegin(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3932 ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);CHKERRQ(ierr); 3933 ierr = PetscLogEventEnd(MAT_SOR,mat,b,x,0);CHKERRQ(ierr); 3934 ierr = PetscObjectStateIncrease((PetscObject)x);CHKERRQ(ierr); 3935 PetscFunctionReturn(0); 3936 } 3937 3938 /* 3939 Default matrix copy routine. 3940 */ 3941 PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str) 3942 { 3943 PetscErrorCode ierr; 3944 PetscInt i,rstart = 0,rend = 0,nz; 3945 const PetscInt *cwork; 3946 const PetscScalar *vwork; 3947 3948 PetscFunctionBegin; 3949 if (B->assembled) { 3950 ierr = MatZeroEntries(B);CHKERRQ(ierr); 3951 } 3952 if (str == SAME_NONZERO_PATTERN) { 3953 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 3954 for (i=rstart; i<rend; i++) { 3955 ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3956 ierr = MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);CHKERRQ(ierr); 3957 ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 3958 } 3959 } else { 3960 ierr = MatAYPX(B,0.0,A,str);CHKERRQ(ierr); 3961 } 3962 ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3963 ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3964 PetscFunctionReturn(0); 3965 } 3966 3967 /*@ 3968 MatCopy - Copies a matrix to another matrix. 3969 3970 Collective on Mat 3971 3972 Input Parameters: 3973 + A - the matrix 3974 - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN 3975 3976 Output Parameter: 3977 . B - where the copy is put 3978 3979 Notes: 3980 If you use SAME_NONZERO_PATTERN then the two matrices had better have the 3981 same nonzero pattern or the routine will crash. 3982 3983 MatCopy() copies the matrix entries of a matrix to another existing 3984 matrix (after first zeroing the second matrix). A related routine is 3985 MatConvert(), which first creates a new matrix and then copies the data. 3986 3987 Level: intermediate 3988 3989 .seealso: MatConvert(), MatDuplicate() 3990 3991 @*/ 3992 PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str) 3993 { 3994 PetscErrorCode ierr; 3995 PetscInt i; 3996 3997 PetscFunctionBegin; 3998 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3999 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4000 PetscValidType(A,1); 4001 PetscValidType(B,2); 4002 PetscCheckSameComm(A,1,B,2); 4003 MatCheckPreallocated(B,2); 4004 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4005 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4006 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); 4007 MatCheckPreallocated(A,1); 4008 if (A == B) PetscFunctionReturn(0); 4009 4010 ierr = PetscLogEventBegin(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4011 if (A->ops->copy) { 4012 ierr = (*A->ops->copy)(A,B,str);CHKERRQ(ierr); 4013 } else { /* generic conversion */ 4014 ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 4015 } 4016 4017 B->stencil.dim = A->stencil.dim; 4018 B->stencil.noc = A->stencil.noc; 4019 for (i=0; i<=A->stencil.dim; i++) { 4020 B->stencil.dims[i] = A->stencil.dims[i]; 4021 B->stencil.starts[i] = A->stencil.starts[i]; 4022 } 4023 4024 ierr = PetscLogEventEnd(MAT_Copy,A,B,0,0);CHKERRQ(ierr); 4025 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4026 PetscFunctionReturn(0); 4027 } 4028 4029 /*@C 4030 MatConvert - Converts a matrix to another matrix, either of the same 4031 or different type. 4032 4033 Collective on Mat 4034 4035 Input Parameters: 4036 + mat - the matrix 4037 . newtype - new matrix type. Use MATSAME to create a new matrix of the 4038 same type as the original matrix. 4039 - reuse - denotes if the destination matrix is to be created or reused. 4040 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 4041 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). 4042 4043 Output Parameter: 4044 . M - pointer to place new matrix 4045 4046 Notes: 4047 MatConvert() first creates a new matrix and then copies the data from 4048 the first matrix. A related routine is MatCopy(), which copies the matrix 4049 entries of one matrix to another already existing matrix context. 4050 4051 Cannot be used to convert a sequential matrix to parallel or parallel to sequential, 4052 the MPI communicator of the generated matrix is always the same as the communicator 4053 of the input matrix. 4054 4055 Level: intermediate 4056 4057 .seealso: MatCopy(), MatDuplicate() 4058 @*/ 4059 PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M) 4060 { 4061 PetscErrorCode ierr; 4062 PetscBool sametype,issame,flg; 4063 char convname[256],mtype[256]; 4064 Mat B; 4065 4066 PetscFunctionBegin; 4067 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4068 PetscValidType(mat,1); 4069 PetscValidPointer(M,3); 4070 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4071 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4072 MatCheckPreallocated(mat,1); 4073 4074 ierr = PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);CHKERRQ(ierr); 4075 if (flg) { 4076 newtype = mtype; 4077 } 4078 ierr = PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);CHKERRQ(ierr); 4079 ierr = PetscStrcmp(newtype,"same",&issame);CHKERRQ(ierr); 4080 if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix"); 4081 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"); 4082 4083 if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) PetscFunctionReturn(0); 4084 4085 if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) { 4086 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4087 } else { 4088 PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL; 4089 const char *prefix[3] = {"seq","mpi",""}; 4090 PetscInt i; 4091 /* 4092 Order of precedence: 4093 0) See if newtype is a superclass of the current matrix. 4094 1) See if a specialized converter is known to the current matrix. 4095 2) See if a specialized converter is known to the desired matrix class. 4096 3) See if a good general converter is registered for the desired class 4097 (as of 6/27/03 only MATMPIADJ falls into this category). 4098 4) See if a good general converter is known for the current matrix. 4099 5) Use a really basic converter. 4100 */ 4101 4102 /* 0) See if newtype is a superclass of the current matrix. 4103 i.e mat is mpiaij and newtype is aij */ 4104 for (i=0; i<2; i++) { 4105 ierr = PetscStrncpy(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4106 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4107 ierr = PetscStrcmp(convname,((PetscObject)mat)->type_name,&flg);CHKERRQ(ierr); 4108 ierr = PetscInfo3(mat,"Check superclass %s %s -> %d\n",convname,((PetscObject)mat)->type_name,flg);CHKERRQ(ierr); 4109 if (flg) { 4110 if (reuse == MAT_INPLACE_MATRIX) { 4111 PetscFunctionReturn(0); 4112 } else if (reuse == MAT_INITIAL_MATRIX && mat->ops->duplicate) { 4113 ierr = (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);CHKERRQ(ierr); 4114 PetscFunctionReturn(0); 4115 } else if (reuse == MAT_REUSE_MATRIX && mat->ops->copy) { 4116 ierr = MatCopy(mat,*M,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4117 PetscFunctionReturn(0); 4118 } 4119 } 4120 } 4121 /* 1) See if a specialized converter is known to the current matrix and the desired class */ 4122 for (i=0; i<3; i++) { 4123 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4124 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4125 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4126 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4127 ierr = PetscStrlcat(convname,issame ? ((PetscObject)mat)->type_name : newtype,sizeof(convname));CHKERRQ(ierr); 4128 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4129 ierr = PetscObjectQueryFunction((PetscObject)mat,convname,&conv);CHKERRQ(ierr); 4130 ierr = PetscInfo3(mat,"Check specialized (1) %s (%s) -> %d\n",convname,((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4131 if (conv) goto foundconv; 4132 } 4133 4134 /* 2) See if a specialized converter is known to the desired matrix class. */ 4135 ierr = MatCreate(PetscObjectComm((PetscObject)mat),&B);CHKERRQ(ierr); 4136 ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);CHKERRQ(ierr); 4137 ierr = MatSetType(B,newtype);CHKERRQ(ierr); 4138 for (i=0; i<3; i++) { 4139 ierr = PetscStrncpy(convname,"MatConvert_",sizeof(convname));CHKERRQ(ierr); 4140 ierr = PetscStrlcat(convname,((PetscObject)mat)->type_name,sizeof(convname));CHKERRQ(ierr); 4141 ierr = PetscStrlcat(convname,"_",sizeof(convname));CHKERRQ(ierr); 4142 ierr = PetscStrlcat(convname,prefix[i],sizeof(convname));CHKERRQ(ierr); 4143 ierr = PetscStrlcat(convname,newtype,sizeof(convname));CHKERRQ(ierr); 4144 ierr = PetscStrlcat(convname,"_C",sizeof(convname));CHKERRQ(ierr); 4145 ierr = PetscObjectQueryFunction((PetscObject)B,convname,&conv);CHKERRQ(ierr); 4146 ierr = PetscInfo3(mat,"Check specialized (2) %s (%s) -> %d\n",convname,((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4147 if (conv) { 4148 ierr = MatDestroy(&B);CHKERRQ(ierr); 4149 goto foundconv; 4150 } 4151 } 4152 4153 /* 3) See if a good general converter is registered for the desired class */ 4154 conv = B->ops->convertfrom; 4155 ierr = PetscInfo2(mat,"Check convertfrom (%s) -> %d\n",((PetscObject)B)->type_name,!!conv);CHKERRQ(ierr); 4156 ierr = MatDestroy(&B);CHKERRQ(ierr); 4157 if (conv) goto foundconv; 4158 4159 /* 4) See if a good general converter is known for the current matrix */ 4160 if (mat->ops->convert) { 4161 conv = mat->ops->convert; 4162 } 4163 ierr = PetscInfo2(mat,"Check general convert (%s) -> %d\n",((PetscObject)mat)->type_name,!!conv);CHKERRQ(ierr); 4164 if (conv) goto foundconv; 4165 4166 /* 5) Use a really basic converter. */ 4167 ierr = PetscInfo(mat,"Using MatConvert_Basic\n");CHKERRQ(ierr); 4168 conv = MatConvert_Basic; 4169 4170 foundconv: 4171 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4172 ierr = (*conv)(mat,newtype,reuse,M);CHKERRQ(ierr); 4173 if (mat->rmap->mapping && mat->cmap->mapping && !(*M)->rmap->mapping && !(*M)->cmap->mapping) { 4174 /* the block sizes must be same if the mappings are copied over */ 4175 (*M)->rmap->bs = mat->rmap->bs; 4176 (*M)->cmap->bs = mat->cmap->bs; 4177 ierr = PetscObjectReference((PetscObject)mat->rmap->mapping);CHKERRQ(ierr); 4178 ierr = PetscObjectReference((PetscObject)mat->cmap->mapping);CHKERRQ(ierr); 4179 (*M)->rmap->mapping = mat->rmap->mapping; 4180 (*M)->cmap->mapping = mat->cmap->mapping; 4181 } 4182 (*M)->stencil.dim = mat->stencil.dim; 4183 (*M)->stencil.noc = mat->stencil.noc; 4184 for (i=0; i<=mat->stencil.dim; i++) { 4185 (*M)->stencil.dims[i] = mat->stencil.dims[i]; 4186 (*M)->stencil.starts[i] = mat->stencil.starts[i]; 4187 } 4188 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4189 } 4190 ierr = PetscObjectStateIncrease((PetscObject)*M);CHKERRQ(ierr); 4191 4192 /* Copy Mat options */ 4193 if (mat->symmetric) {ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);} 4194 if (mat->hermitian) {ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr);} 4195 PetscFunctionReturn(0); 4196 } 4197 4198 /*@C 4199 MatFactorGetSolverType - Returns name of the package providing the factorization routines 4200 4201 Not Collective 4202 4203 Input Parameter: 4204 . mat - the matrix, must be a factored matrix 4205 4206 Output Parameter: 4207 . type - the string name of the package (do not free this string) 4208 4209 Notes: 4210 In Fortran you pass in a empty string and the package name will be copied into it. 4211 (Make sure the string is long enough) 4212 4213 Level: intermediate 4214 4215 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor() 4216 @*/ 4217 PetscErrorCode MatFactorGetSolverType(Mat mat, MatSolverType *type) 4218 { 4219 PetscErrorCode ierr, (*conv)(Mat,MatSolverType*); 4220 4221 PetscFunctionBegin; 4222 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4223 PetscValidType(mat,1); 4224 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 4225 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverType_C",&conv);CHKERRQ(ierr); 4226 if (!conv) { 4227 *type = MATSOLVERPETSC; 4228 } else { 4229 ierr = (*conv)(mat,type);CHKERRQ(ierr); 4230 } 4231 PetscFunctionReturn(0); 4232 } 4233 4234 typedef struct _MatSolverTypeForSpecifcType* MatSolverTypeForSpecifcType; 4235 struct _MatSolverTypeForSpecifcType { 4236 MatType mtype; 4237 PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*); 4238 MatSolverTypeForSpecifcType next; 4239 }; 4240 4241 typedef struct _MatSolverTypeHolder* MatSolverTypeHolder; 4242 struct _MatSolverTypeHolder { 4243 char *name; 4244 MatSolverTypeForSpecifcType handlers; 4245 MatSolverTypeHolder next; 4246 }; 4247 4248 static MatSolverTypeHolder MatSolverTypeHolders = NULL; 4249 4250 /*@C 4251 MatSolvePackageRegister - Registers a MatSolverType that works for a particular matrix type 4252 4253 Input Parameters: 4254 + package - name of the package, for example petsc or superlu 4255 . mtype - the matrix type that works with this package 4256 . ftype - the type of factorization supported by the package 4257 - getfactor - routine that will create the factored matrix ready to be used 4258 4259 Level: intermediate 4260 4261 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4262 @*/ 4263 PetscErrorCode MatSolverTypeRegister(MatSolverType package,MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*)) 4264 { 4265 PetscErrorCode ierr; 4266 MatSolverTypeHolder next = MatSolverTypeHolders,prev = NULL; 4267 PetscBool flg; 4268 MatSolverTypeForSpecifcType inext,iprev = NULL; 4269 4270 PetscFunctionBegin; 4271 ierr = MatInitializePackage();CHKERRQ(ierr); 4272 if (!next) { 4273 ierr = PetscNew(&MatSolverTypeHolders);CHKERRQ(ierr); 4274 ierr = PetscStrallocpy(package,&MatSolverTypeHolders->name);CHKERRQ(ierr); 4275 ierr = PetscNew(&MatSolverTypeHolders->handlers);CHKERRQ(ierr); 4276 ierr = PetscStrallocpy(mtype,(char **)&MatSolverTypeHolders->handlers->mtype);CHKERRQ(ierr); 4277 MatSolverTypeHolders->handlers->getfactor[(int)ftype-1] = getfactor; 4278 PetscFunctionReturn(0); 4279 } 4280 while (next) { 4281 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4282 if (flg) { 4283 if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverTypeHolder is missing handlers"); 4284 inext = next->handlers; 4285 while (inext) { 4286 ierr = PetscStrcasecmp(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4287 if (flg) { 4288 inext->getfactor[(int)ftype-1] = getfactor; 4289 PetscFunctionReturn(0); 4290 } 4291 iprev = inext; 4292 inext = inext->next; 4293 } 4294 ierr = PetscNew(&iprev->next);CHKERRQ(ierr); 4295 ierr = PetscStrallocpy(mtype,(char **)&iprev->next->mtype);CHKERRQ(ierr); 4296 iprev->next->getfactor[(int)ftype-1] = getfactor; 4297 PetscFunctionReturn(0); 4298 } 4299 prev = next; 4300 next = next->next; 4301 } 4302 ierr = PetscNew(&prev->next);CHKERRQ(ierr); 4303 ierr = PetscStrallocpy(package,&prev->next->name);CHKERRQ(ierr); 4304 ierr = PetscNew(&prev->next->handlers);CHKERRQ(ierr); 4305 ierr = PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);CHKERRQ(ierr); 4306 prev->next->handlers->getfactor[(int)ftype-1] = getfactor; 4307 PetscFunctionReturn(0); 4308 } 4309 4310 /*@C 4311 MatSolvePackageGet - Get's the function that creates the factor matrix if it exist 4312 4313 Input Parameters: 4314 + package - name of the package, for example petsc or superlu 4315 . ftype - the type of factorization supported by the package 4316 - mtype - the matrix type that works with this package 4317 4318 Output Parameters: 4319 + foundpackage - PETSC_TRUE if the package was registered 4320 . foundmtype - PETSC_TRUE if the package supports the requested mtype 4321 - getfactor - routine that will create the factored matrix ready to be used or NULL if not found 4322 4323 Level: intermediate 4324 4325 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4326 @*/ 4327 PetscErrorCode MatSolverTypeGet(MatSolverType package,MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*)) 4328 { 4329 PetscErrorCode ierr; 4330 MatSolverTypeHolder next = MatSolverTypeHolders; 4331 PetscBool flg; 4332 MatSolverTypeForSpecifcType inext; 4333 4334 PetscFunctionBegin; 4335 if (foundpackage) *foundpackage = PETSC_FALSE; 4336 if (foundmtype) *foundmtype = PETSC_FALSE; 4337 if (getfactor) *getfactor = NULL; 4338 4339 if (package) { 4340 while (next) { 4341 ierr = PetscStrcasecmp(package,next->name,&flg);CHKERRQ(ierr); 4342 if (flg) { 4343 if (foundpackage) *foundpackage = PETSC_TRUE; 4344 inext = next->handlers; 4345 while (inext) { 4346 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4347 if (flg) { 4348 if (foundmtype) *foundmtype = PETSC_TRUE; 4349 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4350 PetscFunctionReturn(0); 4351 } 4352 inext = inext->next; 4353 } 4354 } 4355 next = next->next; 4356 } 4357 } else { 4358 while (next) { 4359 inext = next->handlers; 4360 while (inext) { 4361 ierr = PetscStrbeginswith(mtype,inext->mtype,&flg);CHKERRQ(ierr); 4362 if (flg && inext->getfactor[(int)ftype-1]) { 4363 if (foundpackage) *foundpackage = PETSC_TRUE; 4364 if (foundmtype) *foundmtype = PETSC_TRUE; 4365 if (getfactor) *getfactor = inext->getfactor[(int)ftype-1]; 4366 PetscFunctionReturn(0); 4367 } 4368 inext = inext->next; 4369 } 4370 next = next->next; 4371 } 4372 } 4373 PetscFunctionReturn(0); 4374 } 4375 4376 PetscErrorCode MatSolverTypeDestroy(void) 4377 { 4378 PetscErrorCode ierr; 4379 MatSolverTypeHolder next = MatSolverTypeHolders,prev; 4380 MatSolverTypeForSpecifcType inext,iprev; 4381 4382 PetscFunctionBegin; 4383 while (next) { 4384 ierr = PetscFree(next->name);CHKERRQ(ierr); 4385 inext = next->handlers; 4386 while (inext) { 4387 ierr = PetscFree(inext->mtype);CHKERRQ(ierr); 4388 iprev = inext; 4389 inext = inext->next; 4390 ierr = PetscFree(iprev);CHKERRQ(ierr); 4391 } 4392 prev = next; 4393 next = next->next; 4394 ierr = PetscFree(prev);CHKERRQ(ierr); 4395 } 4396 MatSolverTypeHolders = NULL; 4397 PetscFunctionReturn(0); 4398 } 4399 4400 /*@C 4401 MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic() 4402 4403 Collective on Mat 4404 4405 Input Parameters: 4406 + mat - the matrix 4407 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4408 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4409 4410 Output Parameters: 4411 . f - the factor matrix used with MatXXFactorSymbolic() calls 4412 4413 Notes: 4414 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4415 such as pastix, superlu, mumps etc. 4416 4417 PETSc must have been ./configure to use the external solver, using the option --download-package 4418 4419 Level: intermediate 4420 4421 .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable() 4422 @*/ 4423 PetscErrorCode MatGetFactor(Mat mat, MatSolverType type,MatFactorType ftype,Mat *f) 4424 { 4425 PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*); 4426 PetscBool foundpackage,foundmtype; 4427 4428 PetscFunctionBegin; 4429 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4430 PetscValidType(mat,1); 4431 4432 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4433 MatCheckPreallocated(mat,1); 4434 4435 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);CHKERRQ(ierr); 4436 if (!foundpackage) { 4437 if (type) { 4438 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type); 4439 } else { 4440 SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>"); 4441 } 4442 } 4443 4444 if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverType %s does not support matrix type %s",type,((PetscObject)mat)->type_name); 4445 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); 4446 4447 #if defined(PETSC_USE_COMPLEX) 4448 if (mat->hermitian && !mat->symmetric && (ftype == MAT_FACTOR_CHOLESKY||ftype == MAT_FACTOR_ICC)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Hermitian CHOLESKY or ICC Factor is not supported"); 4449 #endif 4450 4451 ierr = (*conv)(mat,ftype,f);CHKERRQ(ierr); 4452 PetscFunctionReturn(0); 4453 } 4454 4455 /*@C 4456 MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type 4457 4458 Not Collective 4459 4460 Input Parameters: 4461 + mat - the matrix 4462 . type - name of solver type, for example, superlu, petsc (to use PETSc's default) 4463 - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU, 4464 4465 Output Parameter: 4466 . flg - PETSC_TRUE if the factorization is available 4467 4468 Notes: 4469 Some PETSc matrix formats have alternative solvers available that are contained in alternative packages 4470 such as pastix, superlu, mumps etc. 4471 4472 PETSc must have been ./configure to use the external solver, using the option --download-package 4473 4474 Level: intermediate 4475 4476 .seealso: MatCopy(), MatDuplicate(), MatGetFactor() 4477 @*/ 4478 PetscErrorCode MatGetFactorAvailable(Mat mat, MatSolverType type,MatFactorType ftype,PetscBool *flg) 4479 { 4480 PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*); 4481 4482 PetscFunctionBegin; 4483 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4484 PetscValidType(mat,1); 4485 4486 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4487 MatCheckPreallocated(mat,1); 4488 4489 *flg = PETSC_FALSE; 4490 ierr = MatSolverTypeGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);CHKERRQ(ierr); 4491 if (gconv) { 4492 *flg = PETSC_TRUE; 4493 } 4494 PetscFunctionReturn(0); 4495 } 4496 4497 #include <petscdmtypes.h> 4498 4499 /*@ 4500 MatDuplicate - Duplicates a matrix including the non-zero structure. 4501 4502 Collective on Mat 4503 4504 Input Parameters: 4505 + mat - the matrix 4506 - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN. 4507 See the manual page for MatDuplicateOption for an explanation of these options. 4508 4509 Output Parameter: 4510 . M - pointer to place new matrix 4511 4512 Level: intermediate 4513 4514 Notes: 4515 You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN. 4516 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. 4517 4518 .seealso: MatCopy(), MatConvert(), MatDuplicateOption 4519 @*/ 4520 PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M) 4521 { 4522 PetscErrorCode ierr; 4523 Mat B; 4524 PetscInt i; 4525 DM dm; 4526 void (*viewf)(void); 4527 4528 PetscFunctionBegin; 4529 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4530 PetscValidType(mat,1); 4531 PetscValidPointer(M,3); 4532 if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix"); 4533 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4534 MatCheckPreallocated(mat,1); 4535 4536 *M = 0; 4537 if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type"); 4538 ierr = PetscLogEventBegin(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4539 ierr = (*mat->ops->duplicate)(mat,op,M);CHKERRQ(ierr); 4540 B = *M; 4541 4542 ierr = MatGetOperation(mat,MATOP_VIEW,&viewf);CHKERRQ(ierr); 4543 if (viewf) { 4544 ierr = MatSetOperation(B,MATOP_VIEW,viewf);CHKERRQ(ierr); 4545 } 4546 4547 B->stencil.dim = mat->stencil.dim; 4548 B->stencil.noc = mat->stencil.noc; 4549 for (i=0; i<=mat->stencil.dim; i++) { 4550 B->stencil.dims[i] = mat->stencil.dims[i]; 4551 B->stencil.starts[i] = mat->stencil.starts[i]; 4552 } 4553 4554 B->nooffproczerorows = mat->nooffproczerorows; 4555 B->nooffprocentries = mat->nooffprocentries; 4556 4557 ierr = PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);CHKERRQ(ierr); 4558 if (dm) { 4559 ierr = PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);CHKERRQ(ierr); 4560 } 4561 ierr = PetscLogEventEnd(MAT_Convert,mat,0,0,0);CHKERRQ(ierr); 4562 ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 4563 PetscFunctionReturn(0); 4564 } 4565 4566 /*@ 4567 MatGetDiagonal - Gets the diagonal of a matrix. 4568 4569 Logically Collective on Mat 4570 4571 Input Parameters: 4572 + mat - the matrix 4573 - v - the vector for storing the diagonal 4574 4575 Output Parameter: 4576 . v - the diagonal of the matrix 4577 4578 Level: intermediate 4579 4580 Note: 4581 Currently only correct in parallel for square matrices. 4582 4583 .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs() 4584 @*/ 4585 PetscErrorCode MatGetDiagonal(Mat mat,Vec v) 4586 { 4587 PetscErrorCode ierr; 4588 4589 PetscFunctionBegin; 4590 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4591 PetscValidType(mat,1); 4592 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4593 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4594 if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4595 MatCheckPreallocated(mat,1); 4596 4597 ierr = (*mat->ops->getdiagonal)(mat,v);CHKERRQ(ierr); 4598 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4599 PetscFunctionReturn(0); 4600 } 4601 4602 /*@C 4603 MatGetRowMin - Gets the minimum value (of the real part) of each 4604 row of the matrix 4605 4606 Logically Collective on Mat 4607 4608 Input Parameters: 4609 . mat - the matrix 4610 4611 Output Parameter: 4612 + v - the vector for storing the maximums 4613 - idx - the indices of the column found for each row (optional) 4614 4615 Level: intermediate 4616 4617 Notes: 4618 The result of this call are the same as if one converted the matrix to dense format 4619 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4620 4621 This code is only implemented for a couple of matrix formats. 4622 4623 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), 4624 MatGetRowMax() 4625 @*/ 4626 PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[]) 4627 { 4628 PetscErrorCode ierr; 4629 4630 PetscFunctionBegin; 4631 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4632 PetscValidType(mat,1); 4633 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4634 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4635 if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4636 MatCheckPreallocated(mat,1); 4637 4638 ierr = (*mat->ops->getrowmin)(mat,v,idx);CHKERRQ(ierr); 4639 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4640 PetscFunctionReturn(0); 4641 } 4642 4643 /*@C 4644 MatGetRowMinAbs - Gets the minimum value (in absolute value) of each 4645 row of the matrix 4646 4647 Logically Collective on Mat 4648 4649 Input Parameters: 4650 . mat - the matrix 4651 4652 Output Parameter: 4653 + v - the vector for storing the minimums 4654 - idx - the indices of the column found for each row (or NULL if not needed) 4655 4656 Level: intermediate 4657 4658 Notes: 4659 if a row is completely empty or has only 0.0 values then the idx[] value for that 4660 row is 0 (the first column). 4661 4662 This code is only implemented for a couple of matrix formats. 4663 4664 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin() 4665 @*/ 4666 PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[]) 4667 { 4668 PetscErrorCode ierr; 4669 4670 PetscFunctionBegin; 4671 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4672 PetscValidType(mat,1); 4673 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4674 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4675 if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4676 MatCheckPreallocated(mat,1); 4677 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 4678 4679 ierr = (*mat->ops->getrowminabs)(mat,v,idx);CHKERRQ(ierr); 4680 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4681 PetscFunctionReturn(0); 4682 } 4683 4684 /*@C 4685 MatGetRowMax - Gets the maximum value (of the real part) of each 4686 row of the matrix 4687 4688 Logically Collective on Mat 4689 4690 Input Parameters: 4691 . mat - the matrix 4692 4693 Output Parameter: 4694 + v - the vector for storing the maximums 4695 - idx - the indices of the column found for each row (optional) 4696 4697 Level: intermediate 4698 4699 Notes: 4700 The result of this call are the same as if one converted the matrix to dense format 4701 and found the minimum value in each row (i.e. the implicit zeros are counted as zeros). 4702 4703 This code is only implemented for a couple of matrix formats. 4704 4705 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMaxAbs(), MatGetRowMin() 4706 @*/ 4707 PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[]) 4708 { 4709 PetscErrorCode ierr; 4710 4711 PetscFunctionBegin; 4712 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4713 PetscValidType(mat,1); 4714 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4715 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4716 if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4717 MatCheckPreallocated(mat,1); 4718 4719 ierr = (*mat->ops->getrowmax)(mat,v,idx);CHKERRQ(ierr); 4720 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4721 PetscFunctionReturn(0); 4722 } 4723 4724 /*@C 4725 MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each 4726 row of the matrix 4727 4728 Logically Collective on Mat 4729 4730 Input Parameters: 4731 . mat - the matrix 4732 4733 Output Parameter: 4734 + v - the vector for storing the maximums 4735 - idx - the indices of the column found for each row (or NULL if not needed) 4736 4737 Level: intermediate 4738 4739 Notes: 4740 if a row is completely empty or has only 0.0 values then the idx[] value for that 4741 row is 0 (the first column). 4742 4743 This code is only implemented for a couple of matrix formats. 4744 4745 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4746 @*/ 4747 PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[]) 4748 { 4749 PetscErrorCode ierr; 4750 4751 PetscFunctionBegin; 4752 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4753 PetscValidType(mat,1); 4754 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4755 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4756 if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4757 MatCheckPreallocated(mat,1); 4758 if (idx) {ierr = PetscArrayzero(idx,mat->rmap->n);CHKERRQ(ierr);} 4759 4760 ierr = (*mat->ops->getrowmaxabs)(mat,v,idx);CHKERRQ(ierr); 4761 ierr = PetscObjectStateIncrease((PetscObject)v);CHKERRQ(ierr); 4762 PetscFunctionReturn(0); 4763 } 4764 4765 /*@ 4766 MatGetRowSum - Gets the sum of each row of the matrix 4767 4768 Logically or Neighborhood Collective on Mat 4769 4770 Input Parameters: 4771 . mat - the matrix 4772 4773 Output Parameter: 4774 . v - the vector for storing the sum of rows 4775 4776 Level: intermediate 4777 4778 Notes: 4779 This code is slow since it is not currently specialized for different formats 4780 4781 .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRowMax(), MatGetRowMin() 4782 @*/ 4783 PetscErrorCode MatGetRowSum(Mat mat, Vec v) 4784 { 4785 Vec ones; 4786 PetscErrorCode ierr; 4787 4788 PetscFunctionBegin; 4789 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4790 PetscValidType(mat,1); 4791 PetscValidHeaderSpecific(v,VEC_CLASSID,2); 4792 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4793 MatCheckPreallocated(mat,1); 4794 ierr = MatCreateVecs(mat,&ones,NULL);CHKERRQ(ierr); 4795 ierr = VecSet(ones,1.);CHKERRQ(ierr); 4796 ierr = MatMult(mat,ones,v);CHKERRQ(ierr); 4797 ierr = VecDestroy(&ones);CHKERRQ(ierr); 4798 PetscFunctionReturn(0); 4799 } 4800 4801 /*@ 4802 MatTranspose - Computes an in-place or out-of-place transpose of a matrix. 4803 4804 Collective on Mat 4805 4806 Input Parameter: 4807 + mat - the matrix to transpose 4808 - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX 4809 4810 Output Parameters: 4811 . B - the transpose 4812 4813 Notes: 4814 If you use MAT_INPLACE_MATRIX then you must pass in &mat for B 4815 4816 MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used 4817 4818 Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed. 4819 4820 Level: intermediate 4821 4822 .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4823 @*/ 4824 PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B) 4825 { 4826 PetscErrorCode ierr; 4827 4828 PetscFunctionBegin; 4829 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4830 PetscValidType(mat,1); 4831 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4832 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4833 if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 4834 if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first"); 4835 if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX"); 4836 MatCheckPreallocated(mat,1); 4837 4838 ierr = PetscLogEventBegin(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4839 ierr = (*mat->ops->transpose)(mat,reuse,B);CHKERRQ(ierr); 4840 ierr = PetscLogEventEnd(MAT_Transpose,mat,0,0,0);CHKERRQ(ierr); 4841 if (B) {ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr);} 4842 PetscFunctionReturn(0); 4843 } 4844 4845 /*@ 4846 MatIsTranspose - Test whether a matrix is another one's transpose, 4847 or its own, in which case it tests symmetry. 4848 4849 Collective on Mat 4850 4851 Input Parameter: 4852 + A - the matrix to test 4853 - B - the matrix to test against, this can equal the first parameter 4854 4855 Output Parameters: 4856 . flg - the result 4857 4858 Notes: 4859 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4860 has a running time of the order of the number of nonzeros; the parallel 4861 test involves parallel copies of the block-offdiagonal parts of the matrix. 4862 4863 Level: intermediate 4864 4865 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian() 4866 @*/ 4867 PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4868 { 4869 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4870 4871 PetscFunctionBegin; 4872 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4873 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4874 PetscValidPointer(flg,3); 4875 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);CHKERRQ(ierr); 4876 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);CHKERRQ(ierr); 4877 *flg = PETSC_FALSE; 4878 if (f && g) { 4879 if (f == g) { 4880 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4881 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test"); 4882 } else { 4883 MatType mattype; 4884 if (!f) { 4885 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 4886 } else { 4887 ierr = MatGetType(B,&mattype);CHKERRQ(ierr); 4888 } 4889 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype); 4890 } 4891 PetscFunctionReturn(0); 4892 } 4893 4894 /*@ 4895 MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate. 4896 4897 Collective on Mat 4898 4899 Input Parameter: 4900 + mat - the matrix to transpose and complex conjugate 4901 - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose 4902 4903 Output Parameters: 4904 . B - the Hermitian 4905 4906 Level: intermediate 4907 4908 .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse 4909 @*/ 4910 PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B) 4911 { 4912 PetscErrorCode ierr; 4913 4914 PetscFunctionBegin; 4915 ierr = MatTranspose(mat,reuse,B);CHKERRQ(ierr); 4916 #if defined(PETSC_USE_COMPLEX) 4917 ierr = MatConjugate(*B);CHKERRQ(ierr); 4918 #endif 4919 PetscFunctionReturn(0); 4920 } 4921 4922 /*@ 4923 MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose, 4924 4925 Collective on Mat 4926 4927 Input Parameter: 4928 + A - the matrix to test 4929 - B - the matrix to test against, this can equal the first parameter 4930 4931 Output Parameters: 4932 . flg - the result 4933 4934 Notes: 4935 Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm 4936 has a running time of the order of the number of nonzeros; the parallel 4937 test involves parallel copies of the block-offdiagonal parts of the matrix. 4938 4939 Level: intermediate 4940 4941 .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose() 4942 @*/ 4943 PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg) 4944 { 4945 PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*); 4946 4947 PetscFunctionBegin; 4948 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4949 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4950 PetscValidPointer(flg,3); 4951 ierr = PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);CHKERRQ(ierr); 4952 ierr = PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);CHKERRQ(ierr); 4953 if (f && g) { 4954 if (f==g) { 4955 ierr = (*f)(A,B,tol,flg);CHKERRQ(ierr); 4956 } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test"); 4957 } 4958 PetscFunctionReturn(0); 4959 } 4960 4961 /*@ 4962 MatPermute - Creates a new matrix with rows and columns permuted from the 4963 original. 4964 4965 Collective on Mat 4966 4967 Input Parameters: 4968 + mat - the matrix to permute 4969 . row - row permutation, each processor supplies only the permutation for its rows 4970 - col - column permutation, each processor supplies only the permutation for its columns 4971 4972 Output Parameters: 4973 . B - the permuted matrix 4974 4975 Level: advanced 4976 4977 Note: 4978 The index sets map from row/col of permuted matrix to row/col of original matrix. 4979 The index sets should be on the same communicator as Mat and have the same local sizes. 4980 4981 .seealso: MatGetOrdering(), ISAllGather() 4982 4983 @*/ 4984 PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B) 4985 { 4986 PetscErrorCode ierr; 4987 4988 PetscFunctionBegin; 4989 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 4990 PetscValidType(mat,1); 4991 PetscValidHeaderSpecific(row,IS_CLASSID,2); 4992 PetscValidHeaderSpecific(col,IS_CLASSID,3); 4993 PetscValidPointer(B,4); 4994 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4995 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4996 if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name); 4997 MatCheckPreallocated(mat,1); 4998 4999 ierr = (*mat->ops->permute)(mat,row,col,B);CHKERRQ(ierr); 5000 ierr = PetscObjectStateIncrease((PetscObject)*B);CHKERRQ(ierr); 5001 PetscFunctionReturn(0); 5002 } 5003 5004 /*@ 5005 MatEqual - Compares two matrices. 5006 5007 Collective on Mat 5008 5009 Input Parameters: 5010 + A - the first matrix 5011 - B - the second matrix 5012 5013 Output Parameter: 5014 . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise. 5015 5016 Level: intermediate 5017 5018 @*/ 5019 PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg) 5020 { 5021 PetscErrorCode ierr; 5022 5023 PetscFunctionBegin; 5024 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 5025 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 5026 PetscValidType(A,1); 5027 PetscValidType(B,2); 5028 PetscValidIntPointer(flg,3); 5029 PetscCheckSameComm(A,1,B,2); 5030 MatCheckPreallocated(B,2); 5031 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5032 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5033 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); 5034 if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name); 5035 if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name); 5036 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); 5037 MatCheckPreallocated(A,1); 5038 5039 ierr = (*A->ops->equal)(A,B,flg);CHKERRQ(ierr); 5040 PetscFunctionReturn(0); 5041 } 5042 5043 /*@ 5044 MatDiagonalScale - Scales a matrix on the left and right by diagonal 5045 matrices that are stored as vectors. Either of the two scaling 5046 matrices can be NULL. 5047 5048 Collective on Mat 5049 5050 Input Parameters: 5051 + mat - the matrix to be scaled 5052 . l - the left scaling vector (or NULL) 5053 - r - the right scaling vector (or NULL) 5054 5055 Notes: 5056 MatDiagonalScale() computes A = LAR, where 5057 L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector) 5058 The L scales the rows of the matrix, the R scales the columns of the matrix. 5059 5060 Level: intermediate 5061 5062 5063 .seealso: MatScale(), MatShift(), MatDiagonalSet() 5064 @*/ 5065 PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r) 5066 { 5067 PetscErrorCode ierr; 5068 5069 PetscFunctionBegin; 5070 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5071 PetscValidType(mat,1); 5072 if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5073 if (l) {PetscValidHeaderSpecific(l,VEC_CLASSID,2);PetscCheckSameComm(mat,1,l,2);} 5074 if (r) {PetscValidHeaderSpecific(r,VEC_CLASSID,3);PetscCheckSameComm(mat,1,r,3);} 5075 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5076 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5077 MatCheckPreallocated(mat,1); 5078 5079 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5080 ierr = (*mat->ops->diagonalscale)(mat,l,r);CHKERRQ(ierr); 5081 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5082 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5083 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5084 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5085 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5086 } 5087 #endif 5088 PetscFunctionReturn(0); 5089 } 5090 5091 /*@ 5092 MatScale - Scales all elements of a matrix by a given number. 5093 5094 Logically Collective on Mat 5095 5096 Input Parameters: 5097 + mat - the matrix to be scaled 5098 - a - the scaling value 5099 5100 Output Parameter: 5101 . mat - the scaled matrix 5102 5103 Level: intermediate 5104 5105 .seealso: MatDiagonalScale() 5106 @*/ 5107 PetscErrorCode MatScale(Mat mat,PetscScalar a) 5108 { 5109 PetscErrorCode ierr; 5110 5111 PetscFunctionBegin; 5112 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5113 PetscValidType(mat,1); 5114 if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5115 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5116 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5117 PetscValidLogicalCollectiveScalar(mat,a,2); 5118 MatCheckPreallocated(mat,1); 5119 5120 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5121 if (a != (PetscScalar)1.0) { 5122 ierr = (*mat->ops->scale)(mat,a);CHKERRQ(ierr); 5123 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5124 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5125 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5126 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5127 } 5128 #endif 5129 } 5130 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 5131 PetscFunctionReturn(0); 5132 } 5133 5134 /*@ 5135 MatNorm - Calculates various norms of a matrix. 5136 5137 Collective on Mat 5138 5139 Input Parameters: 5140 + mat - the matrix 5141 - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY 5142 5143 Output Parameters: 5144 . nrm - the resulting norm 5145 5146 Level: intermediate 5147 5148 @*/ 5149 PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm) 5150 { 5151 PetscErrorCode ierr; 5152 5153 PetscFunctionBegin; 5154 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5155 PetscValidType(mat,1); 5156 PetscValidScalarPointer(nrm,3); 5157 5158 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5159 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5160 if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5161 MatCheckPreallocated(mat,1); 5162 5163 ierr = (*mat->ops->norm)(mat,type,nrm);CHKERRQ(ierr); 5164 PetscFunctionReturn(0); 5165 } 5166 5167 /* 5168 This variable is used to prevent counting of MatAssemblyBegin() that 5169 are called from within a MatAssemblyEnd(). 5170 */ 5171 static PetscInt MatAssemblyEnd_InUse = 0; 5172 /*@ 5173 MatAssemblyBegin - Begins assembling the matrix. This routine should 5174 be called after completing all calls to MatSetValues(). 5175 5176 Collective on Mat 5177 5178 Input Parameters: 5179 + mat - the matrix 5180 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5181 5182 Notes: 5183 MatSetValues() generally caches the values. The matrix is ready to 5184 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5185 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5186 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5187 using the matrix. 5188 5189 ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the 5190 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 5191 a global collective operation requring all processes that share the matrix. 5192 5193 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5194 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5195 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5196 5197 Level: beginner 5198 5199 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled() 5200 @*/ 5201 PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type) 5202 { 5203 PetscErrorCode ierr; 5204 5205 PetscFunctionBegin; 5206 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5207 PetscValidType(mat,1); 5208 MatCheckPreallocated(mat,1); 5209 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?"); 5210 if (mat->assembled) { 5211 mat->was_assembled = PETSC_TRUE; 5212 mat->assembled = PETSC_FALSE; 5213 } 5214 5215 if (!MatAssemblyEnd_InUse) { 5216 ierr = PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5217 if (mat->ops->assemblybegin) {ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr);} 5218 ierr = PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);CHKERRQ(ierr); 5219 } else if (mat->ops->assemblybegin) { 5220 ierr = (*mat->ops->assemblybegin)(mat,type);CHKERRQ(ierr); 5221 } 5222 PetscFunctionReturn(0); 5223 } 5224 5225 /*@ 5226 MatAssembled - Indicates if a matrix has been assembled and is ready for 5227 use; for example, in matrix-vector product. 5228 5229 Not Collective 5230 5231 Input Parameter: 5232 . mat - the matrix 5233 5234 Output Parameter: 5235 . assembled - PETSC_TRUE or PETSC_FALSE 5236 5237 Level: advanced 5238 5239 .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin() 5240 @*/ 5241 PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled) 5242 { 5243 PetscFunctionBegin; 5244 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5245 PetscValidPointer(assembled,2); 5246 *assembled = mat->assembled; 5247 PetscFunctionReturn(0); 5248 } 5249 5250 /*@ 5251 MatAssemblyEnd - Completes assembling the matrix. This routine should 5252 be called after MatAssemblyBegin(). 5253 5254 Collective on Mat 5255 5256 Input Parameters: 5257 + mat - the matrix 5258 - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY 5259 5260 Options Database Keys: 5261 + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly() 5262 . -mat_view ::ascii_info_detail - Prints more detailed info 5263 . -mat_view - Prints matrix in ASCII format 5264 . -mat_view ::ascii_matlab - Prints matrix in Matlab format 5265 . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX(). 5266 . -display <name> - Sets display name (default is host) 5267 . -draw_pause <sec> - Sets number of seconds to pause after display 5268 . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: ch_matlab ) 5269 . -viewer_socket_machine <machine> - Machine to use for socket 5270 . -viewer_socket_port <port> - Port number to use for socket 5271 - -mat_view binary:filename[:append] - Save matrix to file in binary format 5272 5273 Notes: 5274 MatSetValues() generally caches the values. The matrix is ready to 5275 use only after MatAssemblyBegin() and MatAssemblyEnd() have been called. 5276 Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES 5277 in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before 5278 using the matrix. 5279 5280 Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed 5281 out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros 5282 before MAT_FINAL_ASSEMBLY so the space is not compressed out. 5283 5284 Level: beginner 5285 5286 .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen() 5287 @*/ 5288 PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type) 5289 { 5290 PetscErrorCode ierr; 5291 static PetscInt inassm = 0; 5292 PetscBool flg = PETSC_FALSE; 5293 5294 PetscFunctionBegin; 5295 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5296 PetscValidType(mat,1); 5297 5298 inassm++; 5299 MatAssemblyEnd_InUse++; 5300 if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */ 5301 ierr = PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5302 if (mat->ops->assemblyend) { 5303 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5304 } 5305 ierr = PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);CHKERRQ(ierr); 5306 } else if (mat->ops->assemblyend) { 5307 ierr = (*mat->ops->assemblyend)(mat,type);CHKERRQ(ierr); 5308 } 5309 5310 /* Flush assembly is not a true assembly */ 5311 if (type != MAT_FLUSH_ASSEMBLY) { 5312 mat->assembled = PETSC_TRUE; 5313 mat->num_ass++; 5314 mat->ass_nonzerostate = mat->nonzerostate; 5315 } 5316 5317 mat->insertmode = NOT_SET_VALUES; 5318 MatAssemblyEnd_InUse--; 5319 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5320 if (!mat->symmetric_eternal) { 5321 mat->symmetric_set = PETSC_FALSE; 5322 mat->hermitian_set = PETSC_FALSE; 5323 mat->structurally_symmetric_set = PETSC_FALSE; 5324 } 5325 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5326 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5327 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5328 } 5329 #endif 5330 if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) { 5331 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5332 5333 if (mat->checksymmetryonassembly) { 5334 ierr = MatIsSymmetric(mat,mat->checksymmetrytol,&flg);CHKERRQ(ierr); 5335 if (flg) { 5336 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5337 } else { 5338 ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);CHKERRQ(ierr); 5339 } 5340 } 5341 if (mat->nullsp && mat->checknullspaceonassembly) { 5342 ierr = MatNullSpaceTest(mat->nullsp,mat,NULL);CHKERRQ(ierr); 5343 } 5344 } 5345 inassm--; 5346 PetscFunctionReturn(0); 5347 } 5348 5349 /*@ 5350 MatSetOption - Sets a parameter option for a matrix. Some options 5351 may be specific to certain storage formats. Some options 5352 determine how values will be inserted (or added). Sorted, 5353 row-oriented input will generally assemble the fastest. The default 5354 is row-oriented. 5355 5356 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5357 5358 Input Parameters: 5359 + mat - the matrix 5360 . option - the option, one of those listed below (and possibly others), 5361 - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5362 5363 Options Describing Matrix Structure: 5364 + MAT_SPD - symmetric positive definite 5365 . MAT_SYMMETRIC - symmetric in terms of both structure and value 5366 . MAT_HERMITIAN - transpose is the complex conjugation 5367 . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure 5368 - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag 5369 you set to be kept with all future use of the matrix 5370 including after MatAssemblyBegin/End() which could 5371 potentially change the symmetry structure, i.e. you 5372 KNOW the matrix will ALWAYS have the property you set. 5373 5374 5375 Options For Use with MatSetValues(): 5376 Insert a logically dense subblock, which can be 5377 . MAT_ROW_ORIENTED - row-oriented (default) 5378 5379 Note these options reflect the data you pass in with MatSetValues(); it has 5380 nothing to do with how the data is stored internally in the matrix 5381 data structure. 5382 5383 When (re)assembling a matrix, we can restrict the input for 5384 efficiency/debugging purposes. These options include: 5385 + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow) 5386 . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only) 5387 . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries 5388 . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry 5389 . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly 5390 . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if 5391 any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves 5392 performance for very large process counts. 5393 - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset 5394 of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly 5395 functions, instead sending only neighbor messages. 5396 5397 Notes: 5398 Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg! 5399 5400 Some options are relevant only for particular matrix types and 5401 are thus ignored by others. Other options are not supported by 5402 certain matrix types and will generate an error message if set. 5403 5404 If using a Fortran 77 module to compute a matrix, one may need to 5405 use the column-oriented option (or convert to the row-oriented 5406 format). 5407 5408 MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion 5409 that would generate a new entry in the nonzero structure is instead 5410 ignored. Thus, if memory has not alredy been allocated for this particular 5411 data, then the insertion is ignored. For dense matrices, in which 5412 the entire array is allocated, no entries are ever ignored. 5413 Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5414 5415 MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5416 that would generate a new entry in the nonzero structure instead produces 5417 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 5418 5419 MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion 5420 that would generate a new entry that has not been preallocated will 5421 instead produce an error. (Currently supported for AIJ and BAIJ formats 5422 only.) This is a useful flag when debugging matrix memory preallocation. 5423 If this option is set then the MatAssemblyBegin/End() processes has one less global reduction 5424 5425 MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for 5426 other processors should be dropped, rather than stashed. 5427 This is useful if you know that the "owning" processor is also 5428 always generating the correct matrix entries, so that PETSc need 5429 not transfer duplicate entries generated on another processor. 5430 5431 MAT_USE_HASH_TABLE indicates that a hash table be used to improve the 5432 searches during matrix assembly. When this flag is set, the hash table 5433 is created during the first Matrix Assembly. This hash table is 5434 used the next time through, during MatSetVaules()/MatSetVaulesBlocked() 5435 to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag 5436 should be used with MAT_USE_HASH_TABLE flag. This option is currently 5437 supported by MATMPIBAIJ format only. 5438 5439 MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries 5440 are kept in the nonzero structure 5441 5442 MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating 5443 a zero location in the matrix 5444 5445 MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types 5446 5447 MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the 5448 zero row routines and thus improves performance for very large process counts. 5449 5450 MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular 5451 part of the matrix (since they should match the upper triangular part). 5452 5453 MAT_SORTED_FULL - each process provides exactly its local rows; all column indices for a given row are passed in a 5454 single call to MatSetValues(), preallocation is perfect, row oriented, INSERT_VALUES is used. Common 5455 with finite difference schemes with non-periodic boundary conditions. 5456 Notes: 5457 Can only be called after MatSetSizes() and MatSetType() have been set. 5458 5459 Level: intermediate 5460 5461 .seealso: MatOption, Mat 5462 5463 @*/ 5464 PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg) 5465 { 5466 PetscErrorCode ierr; 5467 5468 PetscFunctionBegin; 5469 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5470 PetscValidType(mat,1); 5471 if (op > 0) { 5472 PetscValidLogicalCollectiveEnum(mat,op,2); 5473 PetscValidLogicalCollectiveBool(mat,flg,3); 5474 } 5475 5476 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); 5477 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()"); 5478 5479 switch (op) { 5480 case MAT_NO_OFF_PROC_ENTRIES: 5481 mat->nooffprocentries = flg; 5482 PetscFunctionReturn(0); 5483 break; 5484 case MAT_SUBSET_OFF_PROC_ENTRIES: 5485 mat->assembly_subset = flg; 5486 if (!mat->assembly_subset) { /* See the same logic in VecAssembly wrt VEC_SUBSET_OFF_PROC_ENTRIES */ 5487 #if !defined(PETSC_HAVE_MPIUNI) 5488 ierr = MatStashScatterDestroy_BTS(&mat->stash);CHKERRQ(ierr); 5489 #endif 5490 mat->stash.first_assembly_done = PETSC_FALSE; 5491 } 5492 PetscFunctionReturn(0); 5493 case MAT_NO_OFF_PROC_ZERO_ROWS: 5494 mat->nooffproczerorows = flg; 5495 PetscFunctionReturn(0); 5496 break; 5497 case MAT_SPD: 5498 mat->spd_set = PETSC_TRUE; 5499 mat->spd = flg; 5500 if (flg) { 5501 mat->symmetric = PETSC_TRUE; 5502 mat->structurally_symmetric = PETSC_TRUE; 5503 mat->symmetric_set = PETSC_TRUE; 5504 mat->structurally_symmetric_set = PETSC_TRUE; 5505 } 5506 break; 5507 case MAT_SYMMETRIC: 5508 mat->symmetric = flg; 5509 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5510 mat->symmetric_set = PETSC_TRUE; 5511 mat->structurally_symmetric_set = flg; 5512 #if !defined(PETSC_USE_COMPLEX) 5513 mat->hermitian = flg; 5514 mat->hermitian_set = PETSC_TRUE; 5515 #endif 5516 break; 5517 case MAT_HERMITIAN: 5518 mat->hermitian = flg; 5519 if (flg) mat->structurally_symmetric = PETSC_TRUE; 5520 mat->hermitian_set = PETSC_TRUE; 5521 mat->structurally_symmetric_set = flg; 5522 #if !defined(PETSC_USE_COMPLEX) 5523 mat->symmetric = flg; 5524 mat->symmetric_set = PETSC_TRUE; 5525 #endif 5526 break; 5527 case MAT_STRUCTURALLY_SYMMETRIC: 5528 mat->structurally_symmetric = flg; 5529 mat->structurally_symmetric_set = PETSC_TRUE; 5530 break; 5531 case MAT_SYMMETRY_ETERNAL: 5532 mat->symmetric_eternal = flg; 5533 break; 5534 case MAT_STRUCTURE_ONLY: 5535 mat->structure_only = flg; 5536 break; 5537 case MAT_SORTED_FULL: 5538 mat->sortedfull = flg; 5539 break; 5540 default: 5541 break; 5542 } 5543 if (mat->ops->setoption) { 5544 ierr = (*mat->ops->setoption)(mat,op,flg);CHKERRQ(ierr); 5545 } 5546 PetscFunctionReturn(0); 5547 } 5548 5549 /*@ 5550 MatGetOption - Gets a parameter option that has been set for a matrix. 5551 5552 Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption 5553 5554 Input Parameters: 5555 + mat - the matrix 5556 - option - the option, this only responds to certain options, check the code for which ones 5557 5558 Output Parameter: 5559 . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE) 5560 5561 Notes: 5562 Can only be called after MatSetSizes() and MatSetType() have been set. 5563 5564 Level: intermediate 5565 5566 .seealso: MatOption, MatSetOption() 5567 5568 @*/ 5569 PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg) 5570 { 5571 PetscFunctionBegin; 5572 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5573 PetscValidType(mat,1); 5574 5575 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); 5576 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()"); 5577 5578 switch (op) { 5579 case MAT_NO_OFF_PROC_ENTRIES: 5580 *flg = mat->nooffprocentries; 5581 break; 5582 case MAT_NO_OFF_PROC_ZERO_ROWS: 5583 *flg = mat->nooffproczerorows; 5584 break; 5585 case MAT_SYMMETRIC: 5586 *flg = mat->symmetric; 5587 break; 5588 case MAT_HERMITIAN: 5589 *flg = mat->hermitian; 5590 break; 5591 case MAT_STRUCTURALLY_SYMMETRIC: 5592 *flg = mat->structurally_symmetric; 5593 break; 5594 case MAT_SYMMETRY_ETERNAL: 5595 *flg = mat->symmetric_eternal; 5596 break; 5597 case MAT_SPD: 5598 *flg = mat->spd; 5599 break; 5600 default: 5601 break; 5602 } 5603 PetscFunctionReturn(0); 5604 } 5605 5606 /*@ 5607 MatZeroEntries - Zeros all entries of a matrix. For sparse matrices 5608 this routine retains the old nonzero structure. 5609 5610 Logically Collective on Mat 5611 5612 Input Parameters: 5613 . mat - the matrix 5614 5615 Level: intermediate 5616 5617 Notes: 5618 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. 5619 See the Performance chapter of the users manual for information on preallocating matrices. 5620 5621 .seealso: MatZeroRows() 5622 @*/ 5623 PetscErrorCode MatZeroEntries(Mat mat) 5624 { 5625 PetscErrorCode ierr; 5626 5627 PetscFunctionBegin; 5628 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5629 PetscValidType(mat,1); 5630 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5631 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"); 5632 if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5633 MatCheckPreallocated(mat,1); 5634 5635 ierr = PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5636 ierr = (*mat->ops->zeroentries)(mat);CHKERRQ(ierr); 5637 ierr = PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);CHKERRQ(ierr); 5638 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5639 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5640 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5641 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5642 } 5643 #endif 5644 PetscFunctionReturn(0); 5645 } 5646 5647 /*@ 5648 MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal) 5649 of a set of rows and columns of a matrix. 5650 5651 Collective on Mat 5652 5653 Input Parameters: 5654 + mat - the matrix 5655 . numRows - the number of rows to remove 5656 . rows - the global row indices 5657 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5658 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5659 - b - optional vector of right hand side, that will be adjusted by provided solution 5660 5661 Notes: 5662 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5663 5664 The user can set a value in the diagonal entry (or for the AIJ and 5665 row formats can optionally remove the main diagonal entry from the 5666 nonzero structure as well, by passing 0.0 as the final argument). 5667 5668 For the parallel case, all processes that share the matrix (i.e., 5669 those in the communicator used for matrix creation) MUST call this 5670 routine, regardless of whether any rows being zeroed are owned by 5671 them. 5672 5673 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5674 list only rows local to itself). 5675 5676 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5677 5678 Level: intermediate 5679 5680 .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5681 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5682 @*/ 5683 PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5684 { 5685 PetscErrorCode ierr; 5686 5687 PetscFunctionBegin; 5688 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5689 PetscValidType(mat,1); 5690 if (numRows) PetscValidIntPointer(rows,3); 5691 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5692 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5693 if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5694 MatCheckPreallocated(mat,1); 5695 5696 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5697 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5698 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5699 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5700 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5701 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5702 } 5703 #endif 5704 PetscFunctionReturn(0); 5705 } 5706 5707 /*@ 5708 MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal) 5709 of a set of rows and columns of a matrix. 5710 5711 Collective on Mat 5712 5713 Input Parameters: 5714 + mat - the matrix 5715 . is - the rows to zero 5716 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5717 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5718 - b - optional vector of right hand side, that will be adjusted by provided solution 5719 5720 Notes: 5721 This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix. 5722 5723 The user can set a value in the diagonal entry (or for the AIJ and 5724 row formats can optionally remove the main diagonal entry from the 5725 nonzero structure as well, by passing 0.0 as the final argument). 5726 5727 For the parallel case, all processes that share the matrix (i.e., 5728 those in the communicator used for matrix creation) MUST call this 5729 routine, regardless of whether any rows being zeroed are owned by 5730 them. 5731 5732 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5733 list only rows local to itself). 5734 5735 The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine. 5736 5737 Level: intermediate 5738 5739 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5740 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil() 5741 @*/ 5742 PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5743 { 5744 PetscErrorCode ierr; 5745 PetscInt numRows; 5746 const PetscInt *rows; 5747 5748 PetscFunctionBegin; 5749 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5750 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5751 PetscValidType(mat,1); 5752 PetscValidType(is,2); 5753 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5754 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5755 ierr = MatZeroRowsColumns(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5756 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5757 PetscFunctionReturn(0); 5758 } 5759 5760 /*@ 5761 MatZeroRows - Zeros all entries (except possibly the main diagonal) 5762 of a set of rows of a matrix. 5763 5764 Collective on Mat 5765 5766 Input Parameters: 5767 + mat - the matrix 5768 . numRows - the number of rows to remove 5769 . rows - the global row indices 5770 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5771 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5772 - b - optional vector of right hand side, that will be adjusted by provided solution 5773 5774 Notes: 5775 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5776 but does not release memory. For the dense and block diagonal 5777 formats this does not alter the nonzero structure. 5778 5779 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5780 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5781 merely zeroed. 5782 5783 The user can set a value in the diagonal entry (or for the AIJ and 5784 row formats can optionally remove the main diagonal entry from the 5785 nonzero structure as well, by passing 0.0 as the final argument). 5786 5787 For the parallel case, all processes that share the matrix (i.e., 5788 those in the communicator used for matrix creation) MUST call this 5789 routine, regardless of whether any rows being zeroed are owned by 5790 them. 5791 5792 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5793 list only rows local to itself). 5794 5795 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5796 owns that are to be zeroed. This saves a global synchronization in the implementation. 5797 5798 Level: intermediate 5799 5800 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5801 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5802 @*/ 5803 PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 5804 { 5805 PetscErrorCode ierr; 5806 5807 PetscFunctionBegin; 5808 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5809 PetscValidType(mat,1); 5810 if (numRows) PetscValidIntPointer(rows,3); 5811 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 5812 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 5813 if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 5814 MatCheckPreallocated(mat,1); 5815 5816 ierr = (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5817 ierr = MatViewFromOptions(mat,NULL,"-mat_view");CHKERRQ(ierr); 5818 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 5819 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 5820 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 5821 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 5822 } 5823 #endif 5824 PetscFunctionReturn(0); 5825 } 5826 5827 /*@ 5828 MatZeroRowsIS - Zeros all entries (except possibly the main diagonal) 5829 of a set of rows of a matrix. 5830 5831 Collective on Mat 5832 5833 Input Parameters: 5834 + mat - the matrix 5835 . is - index set of rows to remove 5836 . diag - value put in all diagonals of eliminated rows 5837 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5838 - b - optional vector of right hand side, that will be adjusted by provided solution 5839 5840 Notes: 5841 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5842 but does not release memory. For the dense and block diagonal 5843 formats this does not alter the nonzero structure. 5844 5845 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5846 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5847 merely zeroed. 5848 5849 The user can set a value in the diagonal entry (or for the AIJ and 5850 row formats can optionally remove the main diagonal entry from the 5851 nonzero structure as well, by passing 0.0 as the final argument). 5852 5853 For the parallel case, all processes that share the matrix (i.e., 5854 those in the communicator used for matrix creation) MUST call this 5855 routine, regardless of whether any rows being zeroed are owned by 5856 them. 5857 5858 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5859 list only rows local to itself). 5860 5861 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 5862 owns that are to be zeroed. This saves a global synchronization in the implementation. 5863 5864 Level: intermediate 5865 5866 .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5867 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5868 @*/ 5869 PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 5870 { 5871 PetscInt numRows; 5872 const PetscInt *rows; 5873 PetscErrorCode ierr; 5874 5875 PetscFunctionBegin; 5876 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5877 PetscValidType(mat,1); 5878 PetscValidHeaderSpecific(is,IS_CLASSID,2); 5879 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 5880 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 5881 ierr = MatZeroRows(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 5882 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 5883 PetscFunctionReturn(0); 5884 } 5885 5886 /*@ 5887 MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal) 5888 of a set of rows of a matrix. These rows must be local to the process. 5889 5890 Collective on Mat 5891 5892 Input Parameters: 5893 + mat - the matrix 5894 . numRows - the number of rows to remove 5895 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5896 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5897 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5898 - b - optional vector of right hand side, that will be adjusted by provided solution 5899 5900 Notes: 5901 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 5902 but does not release memory. For the dense and block diagonal 5903 formats this does not alter the nonzero structure. 5904 5905 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 5906 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 5907 merely zeroed. 5908 5909 The user can set a value in the diagonal entry (or for the AIJ and 5910 row formats can optionally remove the main diagonal entry from the 5911 nonzero structure as well, by passing 0.0 as the final argument). 5912 5913 For the parallel case, all processes that share the matrix (i.e., 5914 those in the communicator used for matrix creation) MUST call this 5915 routine, regardless of whether any rows being zeroed are owned by 5916 them. 5917 5918 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 5919 list only rows local to itself). 5920 5921 The grid coordinates are across the entire grid, not just the local portion 5922 5923 In Fortran idxm and idxn should be declared as 5924 $ MatStencil idxm(4,m) 5925 and the values inserted using 5926 $ idxm(MatStencil_i,1) = i 5927 $ idxm(MatStencil_j,1) = j 5928 $ idxm(MatStencil_k,1) = k 5929 $ idxm(MatStencil_c,1) = c 5930 etc 5931 5932 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 5933 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 5934 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 5935 DM_BOUNDARY_PERIODIC boundary type. 5936 5937 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 5938 a single value per point) you can skip filling those indices. 5939 5940 Level: intermediate 5941 5942 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 5943 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 5944 @*/ 5945 PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 5946 { 5947 PetscInt dim = mat->stencil.dim; 5948 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 5949 PetscInt *dims = mat->stencil.dims+1; 5950 PetscInt *starts = mat->stencil.starts; 5951 PetscInt *dxm = (PetscInt*) rows; 5952 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 5953 PetscErrorCode ierr; 5954 5955 PetscFunctionBegin; 5956 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 5957 PetscValidType(mat,1); 5958 if (numRows) PetscValidIntPointer(rows,3); 5959 5960 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 5961 for (i = 0; i < numRows; ++i) { 5962 /* Skip unused dimensions (they are ordered k, j, i, c) */ 5963 for (j = 0; j < 3-sdim; ++j) dxm++; 5964 /* Local index in X dir */ 5965 tmp = *dxm++ - starts[0]; 5966 /* Loop over remaining dimensions */ 5967 for (j = 0; j < dim-1; ++j) { 5968 /* If nonlocal, set index to be negative */ 5969 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 5970 /* Update local index */ 5971 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 5972 } 5973 /* Skip component slot if necessary */ 5974 if (mat->stencil.noc) dxm++; 5975 /* Local row number */ 5976 if (tmp >= 0) { 5977 jdxm[numNewRows++] = tmp; 5978 } 5979 } 5980 ierr = MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 5981 ierr = PetscFree(jdxm);CHKERRQ(ierr); 5982 PetscFunctionReturn(0); 5983 } 5984 5985 /*@ 5986 MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal) 5987 of a set of rows and columns of a matrix. 5988 5989 Collective on Mat 5990 5991 Input Parameters: 5992 + mat - the matrix 5993 . numRows - the number of rows/columns to remove 5994 . rows - the grid coordinates (and component number when dof > 1) for matrix rows 5995 . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry) 5996 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 5997 - b - optional vector of right hand side, that will be adjusted by provided solution 5998 5999 Notes: 6000 For the AIJ and BAIJ matrix formats this removes the old nonzero structure, 6001 but does not release memory. For the dense and block diagonal 6002 formats this does not alter the nonzero structure. 6003 6004 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6005 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6006 merely zeroed. 6007 6008 The user can set a value in the diagonal entry (or for the AIJ and 6009 row formats can optionally remove the main diagonal entry from the 6010 nonzero structure as well, by passing 0.0 as the final argument). 6011 6012 For the parallel case, all processes that share the matrix (i.e., 6013 those in the communicator used for matrix creation) MUST call this 6014 routine, regardless of whether any rows being zeroed are owned by 6015 them. 6016 6017 Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to 6018 list only rows local to itself, but the row/column numbers are given in local numbering). 6019 6020 The grid coordinates are across the entire grid, not just the local portion 6021 6022 In Fortran idxm and idxn should be declared as 6023 $ MatStencil idxm(4,m) 6024 and the values inserted using 6025 $ idxm(MatStencil_i,1) = i 6026 $ idxm(MatStencil_j,1) = j 6027 $ idxm(MatStencil_k,1) = k 6028 $ idxm(MatStencil_c,1) = c 6029 etc 6030 6031 For periodic boundary conditions use negative indices for values to the left (below 0; that are to be 6032 obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one 6033 etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the 6034 DM_BOUNDARY_PERIODIC boundary type. 6035 6036 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 6037 a single value per point) you can skip filling those indices. 6038 6039 Level: intermediate 6040 6041 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6042 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows() 6043 @*/ 6044 PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b) 6045 { 6046 PetscInt dim = mat->stencil.dim; 6047 PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc); 6048 PetscInt *dims = mat->stencil.dims+1; 6049 PetscInt *starts = mat->stencil.starts; 6050 PetscInt *dxm = (PetscInt*) rows; 6051 PetscInt *jdxm, i, j, tmp, numNewRows = 0; 6052 PetscErrorCode ierr; 6053 6054 PetscFunctionBegin; 6055 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6056 PetscValidType(mat,1); 6057 if (numRows) PetscValidIntPointer(rows,3); 6058 6059 ierr = PetscMalloc1(numRows, &jdxm);CHKERRQ(ierr); 6060 for (i = 0; i < numRows; ++i) { 6061 /* Skip unused dimensions (they are ordered k, j, i, c) */ 6062 for (j = 0; j < 3-sdim; ++j) dxm++; 6063 /* Local index in X dir */ 6064 tmp = *dxm++ - starts[0]; 6065 /* Loop over remaining dimensions */ 6066 for (j = 0; j < dim-1; ++j) { 6067 /* If nonlocal, set index to be negative */ 6068 if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT; 6069 /* Update local index */ 6070 else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1]; 6071 } 6072 /* Skip component slot if necessary */ 6073 if (mat->stencil.noc) dxm++; 6074 /* Local row number */ 6075 if (tmp >= 0) { 6076 jdxm[numNewRows++] = tmp; 6077 } 6078 } 6079 ierr = MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);CHKERRQ(ierr); 6080 ierr = PetscFree(jdxm);CHKERRQ(ierr); 6081 PetscFunctionReturn(0); 6082 } 6083 6084 /*@C 6085 MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal) 6086 of a set of rows of a matrix; using local numbering of rows. 6087 6088 Collective on Mat 6089 6090 Input Parameters: 6091 + mat - the matrix 6092 . numRows - the number of rows to remove 6093 . rows - the global row indices 6094 . diag - value put in all diagonals of eliminated rows 6095 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6096 - b - optional vector of right hand side, that will be adjusted by provided solution 6097 6098 Notes: 6099 Before calling MatZeroRowsLocal(), the user must first set the 6100 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6101 6102 For the AIJ matrix formats this removes the old nonzero structure, 6103 but does not release memory. For the dense and block diagonal 6104 formats this does not alter the nonzero structure. 6105 6106 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6107 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6108 merely zeroed. 6109 6110 The user can set a value in the diagonal entry (or for the AIJ and 6111 row formats can optionally remove the main diagonal entry from the 6112 nonzero structure as well, by passing 0.0 as the final argument). 6113 6114 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6115 owns that are to be zeroed. This saves a global synchronization in the implementation. 6116 6117 Level: intermediate 6118 6119 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(), 6120 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6121 @*/ 6122 PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6123 { 6124 PetscErrorCode ierr; 6125 6126 PetscFunctionBegin; 6127 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6128 PetscValidType(mat,1); 6129 if (numRows) PetscValidIntPointer(rows,3); 6130 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6131 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6132 MatCheckPreallocated(mat,1); 6133 6134 if (mat->ops->zerorowslocal) { 6135 ierr = (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6136 } else { 6137 IS is, newis; 6138 const PetscInt *newRows; 6139 6140 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6141 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6142 ierr = ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);CHKERRQ(ierr); 6143 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6144 ierr = (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6145 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6146 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6147 ierr = ISDestroy(&is);CHKERRQ(ierr); 6148 } 6149 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6150 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6151 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6152 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6153 } 6154 #endif 6155 PetscFunctionReturn(0); 6156 } 6157 6158 /*@ 6159 MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal) 6160 of a set of rows of a matrix; using local numbering of rows. 6161 6162 Collective on Mat 6163 6164 Input Parameters: 6165 + mat - the matrix 6166 . is - index set of rows to remove 6167 . diag - value put in all diagonals of eliminated rows 6168 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6169 - b - optional vector of right hand side, that will be adjusted by provided solution 6170 6171 Notes: 6172 Before calling MatZeroRowsLocalIS(), the user must first set the 6173 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6174 6175 For the AIJ matrix formats this removes the old nonzero structure, 6176 but does not release memory. For the dense and block diagonal 6177 formats this does not alter the nonzero structure. 6178 6179 If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure 6180 of the matrix is not changed (even for AIJ and BAIJ matrices) the values are 6181 merely zeroed. 6182 6183 The user can set a value in the diagonal entry (or for the AIJ and 6184 row formats can optionally remove the main diagonal entry from the 6185 nonzero structure as well, by passing 0.0 as the final argument). 6186 6187 You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it 6188 owns that are to be zeroed. This saves a global synchronization in the implementation. 6189 6190 Level: intermediate 6191 6192 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6193 MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6194 @*/ 6195 PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6196 { 6197 PetscErrorCode ierr; 6198 PetscInt numRows; 6199 const PetscInt *rows; 6200 6201 PetscFunctionBegin; 6202 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6203 PetscValidType(mat,1); 6204 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6205 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6206 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6207 MatCheckPreallocated(mat,1); 6208 6209 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6210 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6211 ierr = MatZeroRowsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6212 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6213 PetscFunctionReturn(0); 6214 } 6215 6216 /*@ 6217 MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal) 6218 of a set of rows and columns of a matrix; using local numbering of rows. 6219 6220 Collective on Mat 6221 6222 Input Parameters: 6223 + mat - the matrix 6224 . numRows - the number of rows to remove 6225 . rows - the global row indices 6226 . diag - value put in all diagonals of eliminated rows 6227 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6228 - b - optional vector of right hand side, that will be adjusted by provided solution 6229 6230 Notes: 6231 Before calling MatZeroRowsColumnsLocal(), the user must first set the 6232 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6233 6234 The user can set a value in the diagonal entry (or for the AIJ and 6235 row formats can optionally remove the main diagonal entry from the 6236 nonzero structure as well, by passing 0.0 as the final argument). 6237 6238 Level: intermediate 6239 6240 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6241 MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6242 @*/ 6243 PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 6244 { 6245 PetscErrorCode ierr; 6246 IS is, newis; 6247 const PetscInt *newRows; 6248 6249 PetscFunctionBegin; 6250 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6251 PetscValidType(mat,1); 6252 if (numRows) PetscValidIntPointer(rows,3); 6253 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6254 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6255 MatCheckPreallocated(mat,1); 6256 6257 if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first"); 6258 ierr = ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);CHKERRQ(ierr); 6259 ierr = ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);CHKERRQ(ierr); 6260 ierr = ISGetIndices(newis,&newRows);CHKERRQ(ierr); 6261 ierr = (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);CHKERRQ(ierr); 6262 ierr = ISRestoreIndices(newis,&newRows);CHKERRQ(ierr); 6263 ierr = ISDestroy(&newis);CHKERRQ(ierr); 6264 ierr = ISDestroy(&is);CHKERRQ(ierr); 6265 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 6266 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) 6267 if (mat->valid_GPU_matrix != PETSC_OFFLOAD_UNALLOCATED) { 6268 mat->valid_GPU_matrix = PETSC_OFFLOAD_CPU; 6269 } 6270 #endif 6271 PetscFunctionReturn(0); 6272 } 6273 6274 /*@ 6275 MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal) 6276 of a set of rows and columns of a matrix; using local numbering of rows. 6277 6278 Collective on Mat 6279 6280 Input Parameters: 6281 + mat - the matrix 6282 . is - index set of rows to remove 6283 . diag - value put in all diagonals of eliminated rows 6284 . x - optional vector of solutions for zeroed rows (other entries in vector are not used) 6285 - b - optional vector of right hand side, that will be adjusted by provided solution 6286 6287 Notes: 6288 Before calling MatZeroRowsColumnsLocalIS(), the user must first set the 6289 local-to-global mapping by calling MatSetLocalToGlobalMapping(). 6290 6291 The user can set a value in the diagonal entry (or for the AIJ and 6292 row formats can optionally remove the main diagonal entry from the 6293 nonzero structure as well, by passing 0.0 as the final argument). 6294 6295 Level: intermediate 6296 6297 .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), 6298 MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil() 6299 @*/ 6300 PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b) 6301 { 6302 PetscErrorCode ierr; 6303 PetscInt numRows; 6304 const PetscInt *rows; 6305 6306 PetscFunctionBegin; 6307 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6308 PetscValidType(mat,1); 6309 PetscValidHeaderSpecific(is,IS_CLASSID,2); 6310 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6311 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6312 MatCheckPreallocated(mat,1); 6313 6314 ierr = ISGetLocalSize(is,&numRows);CHKERRQ(ierr); 6315 ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 6316 ierr = MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);CHKERRQ(ierr); 6317 ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 6318 PetscFunctionReturn(0); 6319 } 6320 6321 /*@C 6322 MatGetSize - Returns the numbers of rows and columns in a matrix. 6323 6324 Not Collective 6325 6326 Input Parameter: 6327 . mat - the matrix 6328 6329 Output Parameters: 6330 + m - the number of global rows 6331 - n - the number of global columns 6332 6333 Note: both output parameters can be NULL on input. 6334 6335 Level: beginner 6336 6337 .seealso: MatGetLocalSize() 6338 @*/ 6339 PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n) 6340 { 6341 PetscFunctionBegin; 6342 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6343 if (m) *m = mat->rmap->N; 6344 if (n) *n = mat->cmap->N; 6345 PetscFunctionReturn(0); 6346 } 6347 6348 /*@C 6349 MatGetLocalSize - Returns the number of rows and columns in a matrix 6350 stored locally. This information may be implementation dependent, so 6351 use with care. 6352 6353 Not Collective 6354 6355 Input Parameters: 6356 . mat - the matrix 6357 6358 Output Parameters: 6359 + m - the number of local rows 6360 - n - the number of local columns 6361 6362 Note: both output parameters can be NULL on input. 6363 6364 Level: beginner 6365 6366 .seealso: MatGetSize() 6367 @*/ 6368 PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n) 6369 { 6370 PetscFunctionBegin; 6371 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6372 if (m) PetscValidIntPointer(m,2); 6373 if (n) PetscValidIntPointer(n,3); 6374 if (m) *m = mat->rmap->n; 6375 if (n) *n = mat->cmap->n; 6376 PetscFunctionReturn(0); 6377 } 6378 6379 /*@C 6380 MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6381 this processor. (The columns of the "diagonal block") 6382 6383 Not Collective, unless matrix has not been allocated, then collective on Mat 6384 6385 Input Parameters: 6386 . mat - the matrix 6387 6388 Output Parameters: 6389 + m - the global index of the first local column 6390 - n - one more than the global index of the last local column 6391 6392 Notes: 6393 both output parameters can be NULL on input. 6394 6395 Level: developer 6396 6397 .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn() 6398 6399 @*/ 6400 PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n) 6401 { 6402 PetscFunctionBegin; 6403 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6404 PetscValidType(mat,1); 6405 if (m) PetscValidIntPointer(m,2); 6406 if (n) PetscValidIntPointer(n,3); 6407 MatCheckPreallocated(mat,1); 6408 if (m) *m = mat->cmap->rstart; 6409 if (n) *n = mat->cmap->rend; 6410 PetscFunctionReturn(0); 6411 } 6412 6413 /*@C 6414 MatGetOwnershipRange - Returns the range of matrix rows owned by 6415 this processor, assuming that the matrix is laid out with the first 6416 n1 rows on the first processor, the next n2 rows on the second, etc. 6417 For certain parallel layouts this range may not be well defined. 6418 6419 Not Collective 6420 6421 Input Parameters: 6422 . mat - the matrix 6423 6424 Output Parameters: 6425 + m - the global index of the first local row 6426 - n - one more than the global index of the last local row 6427 6428 Note: Both output parameters can be NULL on input. 6429 $ This function requires that the matrix be preallocated. If you have not preallocated, consider using 6430 $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N) 6431 $ and then MPI_Scan() to calculate prefix sums of the local sizes. 6432 6433 Level: beginner 6434 6435 .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock() 6436 6437 @*/ 6438 PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n) 6439 { 6440 PetscFunctionBegin; 6441 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6442 PetscValidType(mat,1); 6443 if (m) PetscValidIntPointer(m,2); 6444 if (n) PetscValidIntPointer(n,3); 6445 MatCheckPreallocated(mat,1); 6446 if (m) *m = mat->rmap->rstart; 6447 if (n) *n = mat->rmap->rend; 6448 PetscFunctionReturn(0); 6449 } 6450 6451 /*@C 6452 MatGetOwnershipRanges - Returns the range of matrix rows owned by 6453 each process 6454 6455 Not Collective, unless matrix has not been allocated, then collective on Mat 6456 6457 Input Parameters: 6458 . mat - the matrix 6459 6460 Output Parameters: 6461 . ranges - start of each processors portion plus one more than the total length at the end 6462 6463 Level: beginner 6464 6465 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn() 6466 6467 @*/ 6468 PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges) 6469 { 6470 PetscErrorCode ierr; 6471 6472 PetscFunctionBegin; 6473 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6474 PetscValidType(mat,1); 6475 MatCheckPreallocated(mat,1); 6476 ierr = PetscLayoutGetRanges(mat->rmap,ranges);CHKERRQ(ierr); 6477 PetscFunctionReturn(0); 6478 } 6479 6480 /*@C 6481 MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by 6482 this processor. (The columns of the "diagonal blocks" for each process) 6483 6484 Not Collective, unless matrix has not been allocated, then collective on Mat 6485 6486 Input Parameters: 6487 . mat - the matrix 6488 6489 Output Parameters: 6490 . ranges - start of each processors portion plus one more then the total length at the end 6491 6492 Level: beginner 6493 6494 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges() 6495 6496 @*/ 6497 PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges) 6498 { 6499 PetscErrorCode ierr; 6500 6501 PetscFunctionBegin; 6502 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6503 PetscValidType(mat,1); 6504 MatCheckPreallocated(mat,1); 6505 ierr = PetscLayoutGetRanges(mat->cmap,ranges);CHKERRQ(ierr); 6506 PetscFunctionReturn(0); 6507 } 6508 6509 /*@C 6510 MatGetOwnershipIS - Get row and column ownership as index sets 6511 6512 Not Collective 6513 6514 Input Arguments: 6515 . A - matrix of type Elemental 6516 6517 Output Arguments: 6518 + rows - rows in which this process owns elements 6519 . cols - columns in which this process owns elements 6520 6521 Level: intermediate 6522 6523 .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL 6524 @*/ 6525 PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols) 6526 { 6527 PetscErrorCode ierr,(*f)(Mat,IS*,IS*); 6528 6529 PetscFunctionBegin; 6530 MatCheckPreallocated(A,1); 6531 ierr = PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);CHKERRQ(ierr); 6532 if (f) { 6533 ierr = (*f)(A,rows,cols);CHKERRQ(ierr); 6534 } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */ 6535 if (rows) {ierr = ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);CHKERRQ(ierr);} 6536 if (cols) {ierr = ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);CHKERRQ(ierr);} 6537 } 6538 PetscFunctionReturn(0); 6539 } 6540 6541 /*@C 6542 MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix. 6543 Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric() 6544 to complete the factorization. 6545 6546 Collective on Mat 6547 6548 Input Parameters: 6549 + mat - the matrix 6550 . row - row permutation 6551 . column - column permutation 6552 - info - structure containing 6553 $ levels - number of levels of fill. 6554 $ expected fill - as ratio of original fill. 6555 $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices 6556 missing diagonal entries) 6557 6558 Output Parameters: 6559 . fact - new matrix that has been symbolically factored 6560 6561 Notes: 6562 See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency. 6563 6564 Most users should employ the simplified KSP interface for linear solvers 6565 instead of working directly with matrix algebra routines such as this. 6566 See, e.g., KSPCreate(). 6567 6568 Level: developer 6569 6570 .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 6571 MatGetOrdering(), MatFactorInfo 6572 6573 Note: this uses the definition of level of fill as in Y. Saad, 2003 6574 6575 Developer Note: fortran interface is not autogenerated as the f90 6576 interface defintion cannot be generated correctly [due to MatFactorInfo] 6577 6578 References: 6579 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6580 @*/ 6581 PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info) 6582 { 6583 PetscErrorCode ierr; 6584 6585 PetscFunctionBegin; 6586 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6587 PetscValidType(mat,1); 6588 PetscValidHeaderSpecific(row,IS_CLASSID,2); 6589 PetscValidHeaderSpecific(col,IS_CLASSID,3); 6590 PetscValidPointer(info,4); 6591 PetscValidPointer(fact,5); 6592 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels); 6593 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6594 if (!(fact)->ops->ilufactorsymbolic) { 6595 MatSolverType spackage; 6596 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6597 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage); 6598 } 6599 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6600 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6601 MatCheckPreallocated(mat,2); 6602 6603 ierr = PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6604 ierr = (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);CHKERRQ(ierr); 6605 ierr = PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);CHKERRQ(ierr); 6606 PetscFunctionReturn(0); 6607 } 6608 6609 /*@C 6610 MatICCFactorSymbolic - Performs symbolic incomplete 6611 Cholesky factorization for a symmetric matrix. Use 6612 MatCholeskyFactorNumeric() to complete the factorization. 6613 6614 Collective on Mat 6615 6616 Input Parameters: 6617 + mat - the matrix 6618 . perm - row and column permutation 6619 - info - structure containing 6620 $ levels - number of levels of fill. 6621 $ expected fill - as ratio of original fill. 6622 6623 Output Parameter: 6624 . fact - the factored matrix 6625 6626 Notes: 6627 Most users should employ the KSP interface for linear solvers 6628 instead of working directly with matrix algebra routines such as this. 6629 See, e.g., KSPCreate(). 6630 6631 Level: developer 6632 6633 .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo 6634 6635 Note: this uses the definition of level of fill as in Y. Saad, 2003 6636 6637 Developer Note: fortran interface is not autogenerated as the f90 6638 interface defintion cannot be generated correctly [due to MatFactorInfo] 6639 6640 References: 6641 Y. Saad, Iterative methods for sparse linear systems Philadelphia: Society for Industrial and Applied Mathematics, 2003 6642 @*/ 6643 PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info) 6644 { 6645 PetscErrorCode ierr; 6646 6647 PetscFunctionBegin; 6648 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6649 PetscValidType(mat,1); 6650 PetscValidHeaderSpecific(perm,IS_CLASSID,2); 6651 PetscValidPointer(info,3); 6652 PetscValidPointer(fact,4); 6653 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6654 if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels); 6655 if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill); 6656 if (!(fact)->ops->iccfactorsymbolic) { 6657 MatSolverType spackage; 6658 ierr = MatFactorGetSolverType(fact,&spackage);CHKERRQ(ierr); 6659 SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage); 6660 } 6661 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6662 MatCheckPreallocated(mat,2); 6663 6664 ierr = PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6665 ierr = (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);CHKERRQ(ierr); 6666 ierr = PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);CHKERRQ(ierr); 6667 PetscFunctionReturn(0); 6668 } 6669 6670 /*@C 6671 MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat 6672 points to an array of valid matrices, they may be reused to store the new 6673 submatrices. 6674 6675 Collective on Mat 6676 6677 Input Parameters: 6678 + mat - the matrix 6679 . n - the number of submatrixes to be extracted (on this processor, may be zero) 6680 . irow, icol - index sets of rows and columns to extract 6681 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6682 6683 Output Parameter: 6684 . submat - the array of submatrices 6685 6686 Notes: 6687 MatCreateSubMatrices() can extract ONLY sequential submatrices 6688 (from both sequential and parallel matrices). Use MatCreateSubMatrix() 6689 to extract a parallel submatrix. 6690 6691 Some matrix types place restrictions on the row and column 6692 indices, such as that they be sorted or that they be equal to each other. 6693 6694 The index sets may not have duplicate entries. 6695 6696 When extracting submatrices from a parallel matrix, each processor can 6697 form a different submatrix by setting the rows and columns of its 6698 individual index sets according to the local submatrix desired. 6699 6700 When finished using the submatrices, the user should destroy 6701 them with MatDestroySubMatrices(). 6702 6703 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 6704 original matrix has not changed from that last call to MatCreateSubMatrices(). 6705 6706 This routine creates the matrices in submat; you should NOT create them before 6707 calling it. It also allocates the array of matrix pointers submat. 6708 6709 For BAIJ matrices the index sets must respect the block structure, that is if they 6710 request one row/column in a block, they must request all rows/columns that are in 6711 that block. For example, if the block size is 2 you cannot request just row 0 and 6712 column 0. 6713 6714 Fortran Note: 6715 The Fortran interface is slightly different from that given below; it 6716 requires one to pass in as submat a Mat (integer) array of size at least n+1. 6717 6718 Level: advanced 6719 6720 6721 .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6722 @*/ 6723 PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6724 { 6725 PetscErrorCode ierr; 6726 PetscInt i; 6727 PetscBool eq; 6728 6729 PetscFunctionBegin; 6730 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6731 PetscValidType(mat,1); 6732 if (n) { 6733 PetscValidPointer(irow,3); 6734 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6735 PetscValidPointer(icol,4); 6736 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6737 } 6738 PetscValidPointer(submat,6); 6739 if (n && scall == MAT_REUSE_MATRIX) { 6740 PetscValidPointer(*submat,6); 6741 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6742 } 6743 if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6744 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6745 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6746 MatCheckPreallocated(mat,1); 6747 6748 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6749 ierr = (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6750 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6751 for (i=0; i<n; i++) { 6752 (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */ 6753 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6754 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6755 if (eq) { 6756 if (mat->symmetric) { 6757 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6758 } else if (mat->hermitian) { 6759 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6760 } else if (mat->structurally_symmetric) { 6761 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6762 } 6763 } 6764 } 6765 } 6766 PetscFunctionReturn(0); 6767 } 6768 6769 /*@C 6770 MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms). 6771 6772 Collective on Mat 6773 6774 Input Parameters: 6775 + mat - the matrix 6776 . n - the number of submatrixes to be extracted 6777 . irow, icol - index sets of rows and columns to extract 6778 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 6779 6780 Output Parameter: 6781 . submat - the array of submatrices 6782 6783 Level: advanced 6784 6785 6786 .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse 6787 @*/ 6788 PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[]) 6789 { 6790 PetscErrorCode ierr; 6791 PetscInt i; 6792 PetscBool eq; 6793 6794 PetscFunctionBegin; 6795 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6796 PetscValidType(mat,1); 6797 if (n) { 6798 PetscValidPointer(irow,3); 6799 PetscValidHeaderSpecific(*irow,IS_CLASSID,3); 6800 PetscValidPointer(icol,4); 6801 PetscValidHeaderSpecific(*icol,IS_CLASSID,4); 6802 } 6803 PetscValidPointer(submat,6); 6804 if (n && scall == MAT_REUSE_MATRIX) { 6805 PetscValidPointer(*submat,6); 6806 PetscValidHeaderSpecific(**submat,MAT_CLASSID,6); 6807 } 6808 if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 6809 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 6810 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6811 MatCheckPreallocated(mat,1); 6812 6813 ierr = PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6814 ierr = (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);CHKERRQ(ierr); 6815 ierr = PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);CHKERRQ(ierr); 6816 for (i=0; i<n; i++) { 6817 if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) { 6818 ierr = ISEqual(irow[i],icol[i],&eq);CHKERRQ(ierr); 6819 if (eq) { 6820 if (mat->symmetric) { 6821 ierr = MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6822 } else if (mat->hermitian) { 6823 ierr = MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 6824 } else if (mat->structurally_symmetric) { 6825 ierr = MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 6826 } 6827 } 6828 } 6829 } 6830 PetscFunctionReturn(0); 6831 } 6832 6833 /*@C 6834 MatDestroyMatrices - Destroys an array of matrices. 6835 6836 Collective on Mat 6837 6838 Input Parameters: 6839 + n - the number of local matrices 6840 - mat - the matrices (note that this is a pointer to the array of matrices) 6841 6842 Level: advanced 6843 6844 Notes: 6845 Frees not only the matrices, but also the array that contains the matrices 6846 In Fortran will not free the array. 6847 6848 .seealso: MatCreateSubMatrices() MatDestroySubMatrices() 6849 @*/ 6850 PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[]) 6851 { 6852 PetscErrorCode ierr; 6853 PetscInt i; 6854 6855 PetscFunctionBegin; 6856 if (!*mat) PetscFunctionReturn(0); 6857 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6858 PetscValidPointer(mat,2); 6859 6860 for (i=0; i<n; i++) { 6861 ierr = MatDestroy(&(*mat)[i]);CHKERRQ(ierr); 6862 } 6863 6864 /* memory is allocated even if n = 0 */ 6865 ierr = PetscFree(*mat);CHKERRQ(ierr); 6866 PetscFunctionReturn(0); 6867 } 6868 6869 /*@C 6870 MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices(). 6871 6872 Collective on Mat 6873 6874 Input Parameters: 6875 + n - the number of local matrices 6876 - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling 6877 sequence of MatCreateSubMatrices()) 6878 6879 Level: advanced 6880 6881 Notes: 6882 Frees not only the matrices, but also the array that contains the matrices 6883 In Fortran will not free the array. 6884 6885 .seealso: MatCreateSubMatrices() 6886 @*/ 6887 PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[]) 6888 { 6889 PetscErrorCode ierr; 6890 Mat mat0; 6891 6892 PetscFunctionBegin; 6893 if (!*mat) PetscFunctionReturn(0); 6894 /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */ 6895 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n); 6896 PetscValidPointer(mat,2); 6897 6898 mat0 = (*mat)[0]; 6899 if (mat0 && mat0->ops->destroysubmatrices) { 6900 ierr = (mat0->ops->destroysubmatrices)(n,mat);CHKERRQ(ierr); 6901 } else { 6902 ierr = MatDestroyMatrices(n,mat);CHKERRQ(ierr); 6903 } 6904 PetscFunctionReturn(0); 6905 } 6906 6907 /*@C 6908 MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix. 6909 6910 Collective on Mat 6911 6912 Input Parameters: 6913 . mat - the matrix 6914 6915 Output Parameter: 6916 . matstruct - the sequential matrix with the nonzero structure of mat 6917 6918 Level: intermediate 6919 6920 .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices() 6921 @*/ 6922 PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct) 6923 { 6924 PetscErrorCode ierr; 6925 6926 PetscFunctionBegin; 6927 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6928 PetscValidPointer(matstruct,2); 6929 6930 PetscValidType(mat,1); 6931 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 6932 MatCheckPreallocated(mat,1); 6933 6934 if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name); 6935 ierr = PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6936 ierr = (*mat->ops->getseqnonzerostructure)(mat,matstruct);CHKERRQ(ierr); 6937 ierr = PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);CHKERRQ(ierr); 6938 PetscFunctionReturn(0); 6939 } 6940 6941 /*@C 6942 MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure(). 6943 6944 Collective on Mat 6945 6946 Input Parameters: 6947 . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling 6948 sequence of MatGetSequentialNonzeroStructure()) 6949 6950 Level: advanced 6951 6952 Notes: 6953 Frees not only the matrices, but also the array that contains the matrices 6954 6955 .seealso: MatGetSeqNonzeroStructure() 6956 @*/ 6957 PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat) 6958 { 6959 PetscErrorCode ierr; 6960 6961 PetscFunctionBegin; 6962 PetscValidPointer(mat,1); 6963 ierr = MatDestroy(mat);CHKERRQ(ierr); 6964 PetscFunctionReturn(0); 6965 } 6966 6967 /*@ 6968 MatIncreaseOverlap - Given a set of submatrices indicated by index sets, 6969 replaces the index sets by larger ones that represent submatrices with 6970 additional overlap. 6971 6972 Collective on Mat 6973 6974 Input Parameters: 6975 + mat - the matrix 6976 . n - the number of index sets 6977 . is - the array of index sets (these index sets will changed during the call) 6978 - ov - the additional overlap requested 6979 6980 Options Database: 6981 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 6982 6983 Level: developer 6984 6985 6986 .seealso: MatCreateSubMatrices() 6987 @*/ 6988 PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov) 6989 { 6990 PetscErrorCode ierr; 6991 6992 PetscFunctionBegin; 6993 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6994 PetscValidType(mat,1); 6995 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 6996 if (n) { 6997 PetscValidPointer(is,3); 6998 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 6999 } 7000 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7001 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7002 MatCheckPreallocated(mat,1); 7003 7004 if (!ov) PetscFunctionReturn(0); 7005 if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7006 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7007 ierr = (*mat->ops->increaseoverlap)(mat,n,is,ov);CHKERRQ(ierr); 7008 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7009 PetscFunctionReturn(0); 7010 } 7011 7012 7013 PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt); 7014 7015 /*@ 7016 MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across 7017 a sub communicator, replaces the index sets by larger ones that represent submatrices with 7018 additional overlap. 7019 7020 Collective on Mat 7021 7022 Input Parameters: 7023 + mat - the matrix 7024 . n - the number of index sets 7025 . is - the array of index sets (these index sets will changed during the call) 7026 - ov - the additional overlap requested 7027 7028 Options Database: 7029 . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix) 7030 7031 Level: developer 7032 7033 7034 .seealso: MatCreateSubMatrices() 7035 @*/ 7036 PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov) 7037 { 7038 PetscInt i; 7039 PetscErrorCode ierr; 7040 7041 PetscFunctionBegin; 7042 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7043 PetscValidType(mat,1); 7044 if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n); 7045 if (n) { 7046 PetscValidPointer(is,3); 7047 PetscValidHeaderSpecific(*is,IS_CLASSID,3); 7048 } 7049 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 7050 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7051 MatCheckPreallocated(mat,1); 7052 if (!ov) PetscFunctionReturn(0); 7053 ierr = PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7054 for(i=0; i<n; i++){ 7055 ierr = MatIncreaseOverlapSplit_Single(mat,&is[i],ov);CHKERRQ(ierr); 7056 } 7057 ierr = PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);CHKERRQ(ierr); 7058 PetscFunctionReturn(0); 7059 } 7060 7061 7062 7063 7064 /*@ 7065 MatGetBlockSize - Returns the matrix block size. 7066 7067 Not Collective 7068 7069 Input Parameter: 7070 . mat - the matrix 7071 7072 Output Parameter: 7073 . bs - block size 7074 7075 Notes: 7076 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7077 7078 If the block size has not been set yet this routine returns 1. 7079 7080 Level: intermediate 7081 7082 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes() 7083 @*/ 7084 PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs) 7085 { 7086 PetscFunctionBegin; 7087 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7088 PetscValidIntPointer(bs,2); 7089 *bs = PetscAbs(mat->rmap->bs); 7090 PetscFunctionReturn(0); 7091 } 7092 7093 /*@ 7094 MatGetBlockSizes - Returns the matrix block row and column sizes. 7095 7096 Not Collective 7097 7098 Input Parameter: 7099 . mat - the matrix 7100 7101 Output Parameter: 7102 . rbs - row block size 7103 . cbs - column block size 7104 7105 Notes: 7106 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7107 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7108 7109 If a block size has not been set yet this routine returns 1. 7110 7111 Level: intermediate 7112 7113 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes() 7114 @*/ 7115 PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs) 7116 { 7117 PetscFunctionBegin; 7118 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7119 if (rbs) PetscValidIntPointer(rbs,2); 7120 if (cbs) PetscValidIntPointer(cbs,3); 7121 if (rbs) *rbs = PetscAbs(mat->rmap->bs); 7122 if (cbs) *cbs = PetscAbs(mat->cmap->bs); 7123 PetscFunctionReturn(0); 7124 } 7125 7126 /*@ 7127 MatSetBlockSize - Sets the matrix block size. 7128 7129 Logically Collective on Mat 7130 7131 Input Parameters: 7132 + mat - the matrix 7133 - bs - block size 7134 7135 Notes: 7136 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7137 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later. 7138 7139 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size 7140 is compatible with the matrix local sizes. 7141 7142 Level: intermediate 7143 7144 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes() 7145 @*/ 7146 PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs) 7147 { 7148 PetscErrorCode ierr; 7149 7150 PetscFunctionBegin; 7151 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7152 PetscValidLogicalCollectiveInt(mat,bs,2); 7153 ierr = MatSetBlockSizes(mat,bs,bs);CHKERRQ(ierr); 7154 PetscFunctionReturn(0); 7155 } 7156 7157 /*@ 7158 MatSetVariableBlockSizes - Sets a diagonal blocks of the matrix that need not be of the same size 7159 7160 Logically Collective on Mat 7161 7162 Input Parameters: 7163 + mat - the matrix 7164 . nblocks - the number of blocks on this process 7165 - bsizes - the block sizes 7166 7167 Notes: 7168 Currently used by PCVPBJACOBI for SeqAIJ matrices 7169 7170 Level: intermediate 7171 7172 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatGetVariableBlockSizes() 7173 @*/ 7174 PetscErrorCode MatSetVariableBlockSizes(Mat mat,PetscInt nblocks,PetscInt *bsizes) 7175 { 7176 PetscErrorCode ierr; 7177 PetscInt i,ncnt = 0, nlocal; 7178 7179 PetscFunctionBegin; 7180 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7181 if (nblocks < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local blocks must be great than or equal to zero"); 7182 ierr = MatGetLocalSize(mat,&nlocal,NULL);CHKERRQ(ierr); 7183 for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 7184 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); 7185 ierr = PetscFree(mat->bsizes);CHKERRQ(ierr); 7186 mat->nblocks = nblocks; 7187 ierr = PetscMalloc1(nblocks,&mat->bsizes);CHKERRQ(ierr); 7188 ierr = PetscArraycpy(mat->bsizes,bsizes,nblocks);CHKERRQ(ierr); 7189 PetscFunctionReturn(0); 7190 } 7191 7192 /*@C 7193 MatGetVariableBlockSizes - Gets a diagonal blocks of the matrix that need not be of the same size 7194 7195 Logically Collective on Mat 7196 7197 Input Parameters: 7198 . mat - the matrix 7199 7200 Output Parameters: 7201 + nblocks - the number of blocks on this process 7202 - bsizes - the block sizes 7203 7204 Notes: Currently not supported from Fortran 7205 7206 Level: intermediate 7207 7208 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes(), MatSetVariableBlockSizes() 7209 @*/ 7210 PetscErrorCode MatGetVariableBlockSizes(Mat mat,PetscInt *nblocks,const PetscInt **bsizes) 7211 { 7212 PetscFunctionBegin; 7213 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7214 *nblocks = mat->nblocks; 7215 *bsizes = mat->bsizes; 7216 PetscFunctionReturn(0); 7217 } 7218 7219 /*@ 7220 MatSetBlockSizes - Sets the matrix block row and column sizes. 7221 7222 Logically Collective on Mat 7223 7224 Input Parameters: 7225 + mat - the matrix 7226 - rbs - row block size 7227 - cbs - column block size 7228 7229 Notes: 7230 Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix. 7231 If you pass a different block size for the columns than the rows, the row block size determines the square block storage. 7232 This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later 7233 7234 For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes 7235 are compatible with the matrix local sizes. 7236 7237 The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs(). 7238 7239 Level: intermediate 7240 7241 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes() 7242 @*/ 7243 PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs) 7244 { 7245 PetscErrorCode ierr; 7246 7247 PetscFunctionBegin; 7248 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7249 PetscValidLogicalCollectiveInt(mat,rbs,2); 7250 PetscValidLogicalCollectiveInt(mat,cbs,3); 7251 if (mat->ops->setblocksizes) { 7252 ierr = (*mat->ops->setblocksizes)(mat,rbs,cbs);CHKERRQ(ierr); 7253 } 7254 if (mat->rmap->refcnt) { 7255 ISLocalToGlobalMapping l2g = NULL; 7256 PetscLayout nmap = NULL; 7257 7258 ierr = PetscLayoutDuplicate(mat->rmap,&nmap);CHKERRQ(ierr); 7259 if (mat->rmap->mapping) { 7260 ierr = ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);CHKERRQ(ierr); 7261 } 7262 ierr = PetscLayoutDestroy(&mat->rmap);CHKERRQ(ierr); 7263 mat->rmap = nmap; 7264 mat->rmap->mapping = l2g; 7265 } 7266 if (mat->cmap->refcnt) { 7267 ISLocalToGlobalMapping l2g = NULL; 7268 PetscLayout nmap = NULL; 7269 7270 ierr = PetscLayoutDuplicate(mat->cmap,&nmap);CHKERRQ(ierr); 7271 if (mat->cmap->mapping) { 7272 ierr = ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);CHKERRQ(ierr); 7273 } 7274 ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 7275 mat->cmap = nmap; 7276 mat->cmap->mapping = l2g; 7277 } 7278 ierr = PetscLayoutSetBlockSize(mat->rmap,rbs);CHKERRQ(ierr); 7279 ierr = PetscLayoutSetBlockSize(mat->cmap,cbs);CHKERRQ(ierr); 7280 PetscFunctionReturn(0); 7281 } 7282 7283 /*@ 7284 MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices 7285 7286 Logically Collective on Mat 7287 7288 Input Parameters: 7289 + mat - the matrix 7290 . fromRow - matrix from which to copy row block size 7291 - fromCol - matrix from which to copy column block size (can be same as fromRow) 7292 7293 Level: developer 7294 7295 .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes() 7296 @*/ 7297 PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol) 7298 { 7299 PetscErrorCode ierr; 7300 7301 PetscFunctionBegin; 7302 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7303 PetscValidHeaderSpecific(fromRow,MAT_CLASSID,2); 7304 PetscValidHeaderSpecific(fromCol,MAT_CLASSID,3); 7305 if (fromRow->rmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);CHKERRQ(ierr);} 7306 if (fromCol->cmap->bs > 0) {ierr = PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);CHKERRQ(ierr);} 7307 PetscFunctionReturn(0); 7308 } 7309 7310 /*@ 7311 MatResidual - Default routine to calculate the residual. 7312 7313 Collective on Mat 7314 7315 Input Parameters: 7316 + mat - the matrix 7317 . b - the right-hand-side 7318 - x - the approximate solution 7319 7320 Output Parameter: 7321 . r - location to store the residual 7322 7323 Level: developer 7324 7325 .seealso: PCMGSetResidual() 7326 @*/ 7327 PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r) 7328 { 7329 PetscErrorCode ierr; 7330 7331 PetscFunctionBegin; 7332 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7333 PetscValidHeaderSpecific(b,VEC_CLASSID,2); 7334 PetscValidHeaderSpecific(x,VEC_CLASSID,3); 7335 PetscValidHeaderSpecific(r,VEC_CLASSID,4); 7336 PetscValidType(mat,1); 7337 MatCheckPreallocated(mat,1); 7338 ierr = PetscLogEventBegin(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7339 if (!mat->ops->residual) { 7340 ierr = MatMult(mat,x,r);CHKERRQ(ierr); 7341 ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); 7342 } else { 7343 ierr = (*mat->ops->residual)(mat,b,x,r);CHKERRQ(ierr); 7344 } 7345 ierr = PetscLogEventEnd(MAT_Residual,mat,0,0,0);CHKERRQ(ierr); 7346 PetscFunctionReturn(0); 7347 } 7348 7349 /*@C 7350 MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices. 7351 7352 Collective on Mat 7353 7354 Input Parameters: 7355 + mat - the matrix 7356 . shift - 0 or 1 indicating we want the indices starting at 0 or 1 7357 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized 7358 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7359 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7360 always used. 7361 7362 Output Parameters: 7363 + n - number of rows in the (possibly compressed) matrix 7364 . ia - the row pointers; that is ia[0] = 0, ia[row] = ia[row-1] + number of elements in that row of the matrix 7365 . ja - the column indices 7366 - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers 7367 are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set 7368 7369 Level: developer 7370 7371 Notes: 7372 You CANNOT change any of the ia[] or ja[] values. 7373 7374 Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values. 7375 7376 Fortran Notes: 7377 In Fortran use 7378 $ 7379 $ PetscInt ia(1), ja(1) 7380 $ PetscOffset iia, jja 7381 $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr) 7382 $ ! Access the ith and jth entries via ia(iia + i) and ja(jja + j) 7383 7384 or 7385 $ 7386 $ PetscInt, pointer :: ia(:),ja(:) 7387 $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr) 7388 $ ! Access the ith and jth entries via ia(i) and ja(j) 7389 7390 .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray() 7391 @*/ 7392 PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7393 { 7394 PetscErrorCode ierr; 7395 7396 PetscFunctionBegin; 7397 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7398 PetscValidType(mat,1); 7399 PetscValidIntPointer(n,5); 7400 if (ia) PetscValidIntPointer(ia,6); 7401 if (ja) PetscValidIntPointer(ja,7); 7402 PetscValidIntPointer(done,8); 7403 MatCheckPreallocated(mat,1); 7404 if (!mat->ops->getrowij) *done = PETSC_FALSE; 7405 else { 7406 *done = PETSC_TRUE; 7407 ierr = PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7408 ierr = (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7409 ierr = PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);CHKERRQ(ierr); 7410 } 7411 PetscFunctionReturn(0); 7412 } 7413 7414 /*@C 7415 MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices. 7416 7417 Collective on Mat 7418 7419 Input Parameters: 7420 + mat - the matrix 7421 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7422 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7423 symmetrized 7424 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7425 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7426 always used. 7427 . n - number of columns in the (possibly compressed) matrix 7428 . ia - the column pointers; that is ia[0] = 0, ia[col] = i[col-1] + number of elements in that col of the matrix 7429 - ja - the row indices 7430 7431 Output Parameters: 7432 . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned 7433 7434 Level: developer 7435 7436 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7437 @*/ 7438 PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7439 { 7440 PetscErrorCode ierr; 7441 7442 PetscFunctionBegin; 7443 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7444 PetscValidType(mat,1); 7445 PetscValidIntPointer(n,4); 7446 if (ia) PetscValidIntPointer(ia,5); 7447 if (ja) PetscValidIntPointer(ja,6); 7448 PetscValidIntPointer(done,7); 7449 MatCheckPreallocated(mat,1); 7450 if (!mat->ops->getcolumnij) *done = PETSC_FALSE; 7451 else { 7452 *done = PETSC_TRUE; 7453 ierr = (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7454 } 7455 PetscFunctionReturn(0); 7456 } 7457 7458 /*@C 7459 MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with 7460 MatGetRowIJ(). 7461 7462 Collective on Mat 7463 7464 Input Parameters: 7465 + mat - the matrix 7466 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7467 . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7468 symmetrized 7469 . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7470 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7471 always used. 7472 . n - size of (possibly compressed) matrix 7473 . ia - the row pointers 7474 - ja - the column indices 7475 7476 Output Parameters: 7477 . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7478 7479 Note: 7480 This routine zeros out n, ia, and ja. This is to prevent accidental 7481 us of the array after it has been restored. If you pass NULL, it will 7482 not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid. 7483 7484 Level: developer 7485 7486 .seealso: MatGetRowIJ(), MatRestoreColumnIJ() 7487 @*/ 7488 PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7489 { 7490 PetscErrorCode ierr; 7491 7492 PetscFunctionBegin; 7493 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7494 PetscValidType(mat,1); 7495 if (ia) PetscValidIntPointer(ia,6); 7496 if (ja) PetscValidIntPointer(ja,7); 7497 PetscValidIntPointer(done,8); 7498 MatCheckPreallocated(mat,1); 7499 7500 if (!mat->ops->restorerowij) *done = PETSC_FALSE; 7501 else { 7502 *done = PETSC_TRUE; 7503 ierr = (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7504 if (n) *n = 0; 7505 if (ia) *ia = NULL; 7506 if (ja) *ja = NULL; 7507 } 7508 PetscFunctionReturn(0); 7509 } 7510 7511 /*@C 7512 MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with 7513 MatGetColumnIJ(). 7514 7515 Collective on Mat 7516 7517 Input Parameters: 7518 + mat - the matrix 7519 . shift - 1 or zero indicating we want the indices starting at 0 or 1 7520 - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be 7521 symmetrized 7522 - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the 7523 inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is 7524 always used. 7525 7526 Output Parameters: 7527 + n - size of (possibly compressed) matrix 7528 . ia - the column pointers 7529 . ja - the row indices 7530 - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned 7531 7532 Level: developer 7533 7534 .seealso: MatGetColumnIJ(), MatRestoreRowIJ() 7535 @*/ 7536 PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 7537 { 7538 PetscErrorCode ierr; 7539 7540 PetscFunctionBegin; 7541 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7542 PetscValidType(mat,1); 7543 if (ia) PetscValidIntPointer(ia,5); 7544 if (ja) PetscValidIntPointer(ja,6); 7545 PetscValidIntPointer(done,7); 7546 MatCheckPreallocated(mat,1); 7547 7548 if (!mat->ops->restorecolumnij) *done = PETSC_FALSE; 7549 else { 7550 *done = PETSC_TRUE; 7551 ierr = (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 7552 if (n) *n = 0; 7553 if (ia) *ia = NULL; 7554 if (ja) *ja = NULL; 7555 } 7556 PetscFunctionReturn(0); 7557 } 7558 7559 /*@C 7560 MatColoringPatch -Used inside matrix coloring routines that 7561 use MatGetRowIJ() and/or MatGetColumnIJ(). 7562 7563 Collective on Mat 7564 7565 Input Parameters: 7566 + mat - the matrix 7567 . ncolors - max color value 7568 . n - number of entries in colorarray 7569 - colorarray - array indicating color for each column 7570 7571 Output Parameters: 7572 . iscoloring - coloring generated using colorarray information 7573 7574 Level: developer 7575 7576 .seealso: MatGetRowIJ(), MatGetColumnIJ() 7577 7578 @*/ 7579 PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring) 7580 { 7581 PetscErrorCode ierr; 7582 7583 PetscFunctionBegin; 7584 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7585 PetscValidType(mat,1); 7586 PetscValidIntPointer(colorarray,4); 7587 PetscValidPointer(iscoloring,5); 7588 MatCheckPreallocated(mat,1); 7589 7590 if (!mat->ops->coloringpatch) { 7591 ierr = ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); 7592 } else { 7593 ierr = (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);CHKERRQ(ierr); 7594 } 7595 PetscFunctionReturn(0); 7596 } 7597 7598 7599 /*@ 7600 MatSetUnfactored - Resets a factored matrix to be treated as unfactored. 7601 7602 Logically Collective on Mat 7603 7604 Input Parameter: 7605 . mat - the factored matrix to be reset 7606 7607 Notes: 7608 This routine should be used only with factored matrices formed by in-place 7609 factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE 7610 format). This option can save memory, for example, when solving nonlinear 7611 systems with a matrix-free Newton-Krylov method and a matrix-based, in-place 7612 ILU(0) preconditioner. 7613 7614 Note that one can specify in-place ILU(0) factorization by calling 7615 .vb 7616 PCType(pc,PCILU); 7617 PCFactorSeUseInPlace(pc); 7618 .ve 7619 or by using the options -pc_type ilu -pc_factor_in_place 7620 7621 In-place factorization ILU(0) can also be used as a local 7622 solver for the blocks within the block Jacobi or additive Schwarz 7623 methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc 7624 for details on setting local solver options. 7625 7626 Most users should employ the simplified KSP interface for linear solvers 7627 instead of working directly with matrix algebra routines such as this. 7628 See, e.g., KSPCreate(). 7629 7630 Level: developer 7631 7632 .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace() 7633 7634 @*/ 7635 PetscErrorCode MatSetUnfactored(Mat mat) 7636 { 7637 PetscErrorCode ierr; 7638 7639 PetscFunctionBegin; 7640 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7641 PetscValidType(mat,1); 7642 MatCheckPreallocated(mat,1); 7643 mat->factortype = MAT_FACTOR_NONE; 7644 if (!mat->ops->setunfactored) PetscFunctionReturn(0); 7645 ierr = (*mat->ops->setunfactored)(mat);CHKERRQ(ierr); 7646 PetscFunctionReturn(0); 7647 } 7648 7649 /*MC 7650 MatDenseGetArrayF90 - Accesses a matrix array from Fortran90. 7651 7652 Synopsis: 7653 MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7654 7655 Not collective 7656 7657 Input Parameter: 7658 . x - matrix 7659 7660 Output Parameters: 7661 + xx_v - the Fortran90 pointer to the array 7662 - ierr - error code 7663 7664 Example of Usage: 7665 .vb 7666 PetscScalar, pointer xx_v(:,:) 7667 .... 7668 call MatDenseGetArrayF90(x,xx_v,ierr) 7669 a = xx_v(3) 7670 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7671 .ve 7672 7673 Level: advanced 7674 7675 .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90() 7676 7677 M*/ 7678 7679 /*MC 7680 MatDenseRestoreArrayF90 - Restores a matrix array that has been 7681 accessed with MatDenseGetArrayF90(). 7682 7683 Synopsis: 7684 MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr) 7685 7686 Not collective 7687 7688 Input Parameters: 7689 + x - matrix 7690 - xx_v - the Fortran90 pointer to the array 7691 7692 Output Parameter: 7693 . ierr - error code 7694 7695 Example of Usage: 7696 .vb 7697 PetscScalar, pointer xx_v(:,:) 7698 .... 7699 call MatDenseGetArrayF90(x,xx_v,ierr) 7700 a = xx_v(3) 7701 call MatDenseRestoreArrayF90(x,xx_v,ierr) 7702 .ve 7703 7704 Level: advanced 7705 7706 .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90() 7707 7708 M*/ 7709 7710 7711 /*MC 7712 MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90. 7713 7714 Synopsis: 7715 MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7716 7717 Not collective 7718 7719 Input Parameter: 7720 . x - matrix 7721 7722 Output Parameters: 7723 + xx_v - the Fortran90 pointer to the array 7724 - ierr - error code 7725 7726 Example of Usage: 7727 .vb 7728 PetscScalar, pointer xx_v(:) 7729 .... 7730 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7731 a = xx_v(3) 7732 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7733 .ve 7734 7735 Level: advanced 7736 7737 .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90() 7738 7739 M*/ 7740 7741 /*MC 7742 MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been 7743 accessed with MatSeqAIJGetArrayF90(). 7744 7745 Synopsis: 7746 MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr) 7747 7748 Not collective 7749 7750 Input Parameters: 7751 + x - matrix 7752 - xx_v - the Fortran90 pointer to the array 7753 7754 Output Parameter: 7755 . ierr - error code 7756 7757 Example of Usage: 7758 .vb 7759 PetscScalar, pointer xx_v(:) 7760 .... 7761 call MatSeqAIJGetArrayF90(x,xx_v,ierr) 7762 a = xx_v(3) 7763 call MatSeqAIJRestoreArrayF90(x,xx_v,ierr) 7764 .ve 7765 7766 Level: advanced 7767 7768 .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90() 7769 7770 M*/ 7771 7772 7773 /*@ 7774 MatCreateSubMatrix - Gets a single submatrix on the same number of processors 7775 as the original matrix. 7776 7777 Collective on Mat 7778 7779 Input Parameters: 7780 + mat - the original matrix 7781 . isrow - parallel IS containing the rows this processor should obtain 7782 . 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. 7783 - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 7784 7785 Output Parameter: 7786 . newmat - the new submatrix, of the same type as the old 7787 7788 Level: advanced 7789 7790 Notes: 7791 The submatrix will be able to be multiplied with vectors using the same layout as iscol. 7792 7793 Some matrix types place restrictions on the row and column indices, such 7794 as that they be sorted or that they be equal to each other. 7795 7796 The index sets may not have duplicate entries. 7797 7798 The first time this is called you should use a cll of MAT_INITIAL_MATRIX, 7799 the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls 7800 to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX 7801 will reuse the matrix generated the first time. You should call MatDestroy() on newmat when 7802 you are finished using it. 7803 7804 The communicator of the newly obtained matrix is ALWAYS the same as the communicator of 7805 the input matrix. 7806 7807 If iscol is NULL then all columns are obtained (not supported in Fortran). 7808 7809 Example usage: 7810 Consider the following 8x8 matrix with 34 non-zero values, that is 7811 assembled across 3 processors. Let's assume that proc0 owns 3 rows, 7812 proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown 7813 as follows: 7814 7815 .vb 7816 1 2 0 | 0 3 0 | 0 4 7817 Proc0 0 5 6 | 7 0 0 | 8 0 7818 9 0 10 | 11 0 0 | 12 0 7819 ------------------------------------- 7820 13 0 14 | 15 16 17 | 0 0 7821 Proc1 0 18 0 | 19 20 21 | 0 0 7822 0 0 0 | 22 23 0 | 24 0 7823 ------------------------------------- 7824 Proc2 25 26 27 | 0 0 28 | 29 0 7825 30 0 0 | 31 32 33 | 0 34 7826 .ve 7827 7828 Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is 7829 7830 .vb 7831 2 0 | 0 3 0 | 0 7832 Proc0 5 6 | 7 0 0 | 8 7833 ------------------------------- 7834 Proc1 18 0 | 19 20 21 | 0 7835 ------------------------------- 7836 Proc2 26 27 | 0 0 28 | 29 7837 0 0 | 31 32 33 | 0 7838 .ve 7839 7840 7841 .seealso: MatCreateSubMatrices() 7842 @*/ 7843 PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat) 7844 { 7845 PetscErrorCode ierr; 7846 PetscMPIInt size; 7847 Mat *local; 7848 IS iscoltmp; 7849 7850 PetscFunctionBegin; 7851 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7852 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 7853 if (iscol) PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 7854 PetscValidPointer(newmat,5); 7855 if (cll == MAT_REUSE_MATRIX) PetscValidHeaderSpecific(*newmat,MAT_CLASSID,5); 7856 PetscValidType(mat,1); 7857 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 7858 if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX"); 7859 7860 MatCheckPreallocated(mat,1); 7861 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 7862 7863 if (!iscol || isrow == iscol) { 7864 PetscBool stride; 7865 PetscMPIInt grabentirematrix = 0,grab; 7866 ierr = PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);CHKERRQ(ierr); 7867 if (stride) { 7868 PetscInt first,step,n,rstart,rend; 7869 ierr = ISStrideGetInfo(isrow,&first,&step);CHKERRQ(ierr); 7870 if (step == 1) { 7871 ierr = MatGetOwnershipRange(mat,&rstart,&rend);CHKERRQ(ierr); 7872 if (rstart == first) { 7873 ierr = ISGetLocalSize(isrow,&n);CHKERRQ(ierr); 7874 if (n == rend-rstart) { 7875 grabentirematrix = 1; 7876 } 7877 } 7878 } 7879 } 7880 ierr = MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 7881 if (grab) { 7882 ierr = PetscInfo(mat,"Getting entire matrix as submatrix\n");CHKERRQ(ierr); 7883 if (cll == MAT_INITIAL_MATRIX) { 7884 *newmat = mat; 7885 ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr); 7886 } 7887 PetscFunctionReturn(0); 7888 } 7889 } 7890 7891 if (!iscol) { 7892 ierr = ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);CHKERRQ(ierr); 7893 } else { 7894 iscoltmp = iscol; 7895 } 7896 7897 /* if original matrix is on just one processor then use submatrix generated */ 7898 if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) { 7899 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);CHKERRQ(ierr); 7900 goto setproperties; 7901 } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) { 7902 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);CHKERRQ(ierr); 7903 *newmat = *local; 7904 ierr = PetscFree(local);CHKERRQ(ierr); 7905 goto setproperties; 7906 } else if (!mat->ops->createsubmatrix) { 7907 /* Create a new matrix type that implements the operation using the full matrix */ 7908 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7909 switch (cll) { 7910 case MAT_INITIAL_MATRIX: 7911 ierr = MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);CHKERRQ(ierr); 7912 break; 7913 case MAT_REUSE_MATRIX: 7914 ierr = MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);CHKERRQ(ierr); 7915 break; 7916 default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX"); 7917 } 7918 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7919 goto setproperties; 7920 } 7921 7922 if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 7923 ierr = PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7924 ierr = (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);CHKERRQ(ierr); 7925 ierr = PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);CHKERRQ(ierr); 7926 7927 /* Propagate symmetry information for diagonal blocks */ 7928 setproperties: 7929 if (isrow == iscoltmp) { 7930 if (mat->symmetric_set && mat->symmetric) { 7931 ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 7932 } 7933 if (mat->structurally_symmetric_set && mat->structurally_symmetric) { 7934 ierr = MatSetOption(*newmat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 7935 } 7936 if (mat->hermitian_set && mat->hermitian) { 7937 ierr = MatSetOption(*newmat,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 7938 } 7939 if (mat->spd_set && mat->spd) { 7940 ierr = MatSetOption(*newmat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 7941 } 7942 } 7943 7944 if (!iscol) {ierr = ISDestroy(&iscoltmp);CHKERRQ(ierr);} 7945 if (*newmat && cll == MAT_INITIAL_MATRIX) {ierr = PetscObjectStateIncrease((PetscObject)*newmat);CHKERRQ(ierr);} 7946 PetscFunctionReturn(0); 7947 } 7948 7949 /*@ 7950 MatStashSetInitialSize - sets the sizes of the matrix stash, that is 7951 used during the assembly process to store values that belong to 7952 other processors. 7953 7954 Not Collective 7955 7956 Input Parameters: 7957 + mat - the matrix 7958 . size - the initial size of the stash. 7959 - bsize - the initial size of the block-stash(if used). 7960 7961 Options Database Keys: 7962 + -matstash_initial_size <size> or <size0,size1,...sizep-1> 7963 - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> 7964 7965 Level: intermediate 7966 7967 Notes: 7968 The block-stash is used for values set with MatSetValuesBlocked() while 7969 the stash is used for values set with MatSetValues() 7970 7971 Run with the option -info and look for output of the form 7972 MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs. 7973 to determine the appropriate value, MM, to use for size and 7974 MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs. 7975 to determine the value, BMM to use for bsize 7976 7977 7978 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo() 7979 7980 @*/ 7981 PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize) 7982 { 7983 PetscErrorCode ierr; 7984 7985 PetscFunctionBegin; 7986 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7987 PetscValidType(mat,1); 7988 ierr = MatStashSetInitialSize_Private(&mat->stash,size);CHKERRQ(ierr); 7989 ierr = MatStashSetInitialSize_Private(&mat->bstash,bsize);CHKERRQ(ierr); 7990 PetscFunctionReturn(0); 7991 } 7992 7993 /*@ 7994 MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of 7995 the matrix 7996 7997 Neighbor-wise Collective on Mat 7998 7999 Input Parameters: 8000 + mat - the matrix 8001 . x,y - the vectors 8002 - w - where the result is stored 8003 8004 Level: intermediate 8005 8006 Notes: 8007 w may be the same vector as y. 8008 8009 This allows one to use either the restriction or interpolation (its transpose) 8010 matrix to do the interpolation 8011 8012 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8013 8014 @*/ 8015 PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w) 8016 { 8017 PetscErrorCode ierr; 8018 PetscInt M,N,Ny; 8019 8020 PetscFunctionBegin; 8021 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8022 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8023 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8024 PetscValidHeaderSpecific(w,VEC_CLASSID,4); 8025 PetscValidType(A,1); 8026 MatCheckPreallocated(A,1); 8027 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8028 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8029 if (M == Ny) { 8030 ierr = MatMultAdd(A,x,y,w);CHKERRQ(ierr); 8031 } else { 8032 ierr = MatMultTransposeAdd(A,x,y,w);CHKERRQ(ierr); 8033 } 8034 PetscFunctionReturn(0); 8035 } 8036 8037 /*@ 8038 MatInterpolate - y = A*x or A'*x depending on the shape of 8039 the matrix 8040 8041 Neighbor-wise Collective on Mat 8042 8043 Input Parameters: 8044 + mat - the matrix 8045 - x,y - the vectors 8046 8047 Level: intermediate 8048 8049 Notes: 8050 This allows one to use either the restriction or interpolation (its transpose) 8051 matrix to do the interpolation 8052 8053 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict() 8054 8055 @*/ 8056 PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y) 8057 { 8058 PetscErrorCode ierr; 8059 PetscInt M,N,Ny; 8060 8061 PetscFunctionBegin; 8062 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8063 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8064 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8065 PetscValidType(A,1); 8066 MatCheckPreallocated(A,1); 8067 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8068 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8069 if (M == Ny) { 8070 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8071 } else { 8072 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8073 } 8074 PetscFunctionReturn(0); 8075 } 8076 8077 /*@ 8078 MatRestrict - y = A*x or A'*x 8079 8080 Neighbor-wise Collective on Mat 8081 8082 Input Parameters: 8083 + mat - the matrix 8084 - x,y - the vectors 8085 8086 Level: intermediate 8087 8088 Notes: 8089 This allows one to use either the restriction or interpolation (its transpose) 8090 matrix to do the restriction 8091 8092 .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate() 8093 8094 @*/ 8095 PetscErrorCode MatRestrict(Mat A,Vec x,Vec y) 8096 { 8097 PetscErrorCode ierr; 8098 PetscInt M,N,Ny; 8099 8100 PetscFunctionBegin; 8101 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8102 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 8103 PetscValidHeaderSpecific(y,VEC_CLASSID,3); 8104 PetscValidType(A,1); 8105 MatCheckPreallocated(A,1); 8106 8107 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 8108 ierr = VecGetSize(y,&Ny);CHKERRQ(ierr); 8109 if (M == Ny) { 8110 ierr = MatMult(A,x,y);CHKERRQ(ierr); 8111 } else { 8112 ierr = MatMultTranspose(A,x,y);CHKERRQ(ierr); 8113 } 8114 PetscFunctionReturn(0); 8115 } 8116 8117 /*@ 8118 MatGetNullSpace - retrieves the null space of a matrix. 8119 8120 Logically Collective on Mat 8121 8122 Input Parameters: 8123 + mat - the matrix 8124 - nullsp - the null space object 8125 8126 Level: developer 8127 8128 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace() 8129 @*/ 8130 PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp) 8131 { 8132 PetscFunctionBegin; 8133 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8134 PetscValidPointer(nullsp,2); 8135 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->nullsp) ? mat->transnullsp : mat->nullsp; 8136 PetscFunctionReturn(0); 8137 } 8138 8139 /*@ 8140 MatSetNullSpace - attaches a null space to a matrix. 8141 8142 Logically Collective on Mat 8143 8144 Input Parameters: 8145 + mat - the matrix 8146 - nullsp - the null space object 8147 8148 Level: advanced 8149 8150 Notes: 8151 This null space is used by the linear solvers. Overwrites any previous null space that may have been attached 8152 8153 For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should 8154 call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense. 8155 8156 You can remove the null space by calling this routine with an nullsp of NULL 8157 8158 8159 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8160 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). 8161 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 8162 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 8163 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). 8164 8165 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8166 8167 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 8168 routine also automatically calls MatSetTransposeNullSpace(). 8169 8170 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8171 @*/ 8172 PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp) 8173 { 8174 PetscErrorCode ierr; 8175 8176 PetscFunctionBegin; 8177 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8178 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8179 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8180 ierr = MatNullSpaceDestroy(&mat->nullsp);CHKERRQ(ierr); 8181 mat->nullsp = nullsp; 8182 if (mat->symmetric_set && mat->symmetric) { 8183 ierr = MatSetTransposeNullSpace(mat,nullsp);CHKERRQ(ierr); 8184 } 8185 PetscFunctionReturn(0); 8186 } 8187 8188 /*@ 8189 MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix. 8190 8191 Logically Collective on Mat 8192 8193 Input Parameters: 8194 + mat - the matrix 8195 - nullsp - the null space object 8196 8197 Level: developer 8198 8199 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace() 8200 @*/ 8201 PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp) 8202 { 8203 PetscFunctionBegin; 8204 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8205 PetscValidType(mat,1); 8206 PetscValidPointer(nullsp,2); 8207 *nullsp = (mat->symmetric_set && mat->symmetric && !mat->transnullsp) ? mat->nullsp : mat->transnullsp; 8208 PetscFunctionReturn(0); 8209 } 8210 8211 /*@ 8212 MatSetTransposeNullSpace - attaches a null space to a matrix. 8213 8214 Logically Collective on Mat 8215 8216 Input Parameters: 8217 + mat - the matrix 8218 - nullsp - the null space object 8219 8220 Level: advanced 8221 8222 Notes: 8223 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. 8224 You must also call MatSetNullSpace() 8225 8226 8227 The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that 8228 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). 8229 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 8230 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 8231 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). 8232 8233 Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove(). 8234 8235 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove() 8236 @*/ 8237 PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp) 8238 { 8239 PetscErrorCode ierr; 8240 8241 PetscFunctionBegin; 8242 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8243 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8244 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8245 ierr = MatNullSpaceDestroy(&mat->transnullsp);CHKERRQ(ierr); 8246 mat->transnullsp = nullsp; 8247 PetscFunctionReturn(0); 8248 } 8249 8250 /*@ 8251 MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions 8252 This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix. 8253 8254 Logically Collective on Mat 8255 8256 Input Parameters: 8257 + mat - the matrix 8258 - nullsp - the null space object 8259 8260 Level: advanced 8261 8262 Notes: 8263 Overwrites any previous near null space that may have been attached 8264 8265 You can remove the null space by calling this routine with an nullsp of NULL 8266 8267 .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace() 8268 @*/ 8269 PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp) 8270 { 8271 PetscErrorCode ierr; 8272 8273 PetscFunctionBegin; 8274 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8275 PetscValidType(mat,1); 8276 if (nullsp) PetscValidHeaderSpecific(nullsp,MAT_NULLSPACE_CLASSID,2); 8277 MatCheckPreallocated(mat,1); 8278 if (nullsp) {ierr = PetscObjectReference((PetscObject)nullsp);CHKERRQ(ierr);} 8279 ierr = MatNullSpaceDestroy(&mat->nearnullsp);CHKERRQ(ierr); 8280 mat->nearnullsp = nullsp; 8281 PetscFunctionReturn(0); 8282 } 8283 8284 /*@ 8285 MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace() 8286 8287 Not Collective 8288 8289 Input Parameters: 8290 . mat - the matrix 8291 8292 Output Parameters: 8293 . nullsp - the null space object, NULL if not set 8294 8295 Level: developer 8296 8297 .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate() 8298 @*/ 8299 PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp) 8300 { 8301 PetscFunctionBegin; 8302 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8303 PetscValidType(mat,1); 8304 PetscValidPointer(nullsp,2); 8305 MatCheckPreallocated(mat,1); 8306 *nullsp = mat->nearnullsp; 8307 PetscFunctionReturn(0); 8308 } 8309 8310 /*@C 8311 MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix. 8312 8313 Collective on Mat 8314 8315 Input Parameters: 8316 + mat - the matrix 8317 . row - row/column permutation 8318 . fill - expected fill factor >= 1.0 8319 - level - level of fill, for ICC(k) 8320 8321 Notes: 8322 Probably really in-place only when level of fill is zero, otherwise allocates 8323 new space to store factored matrix and deletes previous memory. 8324 8325 Most users should employ the simplified KSP interface for linear solvers 8326 instead of working directly with matrix algebra routines such as this. 8327 See, e.g., KSPCreate(). 8328 8329 Level: developer 8330 8331 8332 .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor() 8333 8334 Developer Note: fortran interface is not autogenerated as the f90 8335 interface defintion cannot be generated correctly [due to MatFactorInfo] 8336 8337 @*/ 8338 PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info) 8339 { 8340 PetscErrorCode ierr; 8341 8342 PetscFunctionBegin; 8343 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8344 PetscValidType(mat,1); 8345 if (row) PetscValidHeaderSpecific(row,IS_CLASSID,2); 8346 PetscValidPointer(info,3); 8347 if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square"); 8348 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 8349 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 8350 if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8351 MatCheckPreallocated(mat,1); 8352 ierr = (*mat->ops->iccfactor)(mat,row,info);CHKERRQ(ierr); 8353 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8354 PetscFunctionReturn(0); 8355 } 8356 8357 /*@ 8358 MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the 8359 ghosted ones. 8360 8361 Not Collective 8362 8363 Input Parameters: 8364 + mat - the matrix 8365 - diag = the diagonal values, including ghost ones 8366 8367 Level: developer 8368 8369 Notes: 8370 Works only for MPIAIJ and MPIBAIJ matrices 8371 8372 .seealso: MatDiagonalScale() 8373 @*/ 8374 PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag) 8375 { 8376 PetscErrorCode ierr; 8377 PetscMPIInt size; 8378 8379 PetscFunctionBegin; 8380 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8381 PetscValidHeaderSpecific(diag,VEC_CLASSID,2); 8382 PetscValidType(mat,1); 8383 8384 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled"); 8385 ierr = PetscLogEventBegin(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8386 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 8387 if (size == 1) { 8388 PetscInt n,m; 8389 ierr = VecGetSize(diag,&n);CHKERRQ(ierr); 8390 ierr = MatGetSize(mat,0,&m);CHKERRQ(ierr); 8391 if (m == n) { 8392 ierr = MatDiagonalScale(mat,0,diag);CHKERRQ(ierr); 8393 } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions"); 8394 } else { 8395 ierr = PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));CHKERRQ(ierr); 8396 } 8397 ierr = PetscLogEventEnd(MAT_Scale,mat,0,0,0);CHKERRQ(ierr); 8398 ierr = PetscObjectStateIncrease((PetscObject)mat);CHKERRQ(ierr); 8399 PetscFunctionReturn(0); 8400 } 8401 8402 /*@ 8403 MatGetInertia - Gets the inertia from a factored matrix 8404 8405 Collective on Mat 8406 8407 Input Parameter: 8408 . mat - the matrix 8409 8410 Output Parameters: 8411 + nneg - number of negative eigenvalues 8412 . nzero - number of zero eigenvalues 8413 - npos - number of positive eigenvalues 8414 8415 Level: advanced 8416 8417 Notes: 8418 Matrix must have been factored by MatCholeskyFactor() 8419 8420 8421 @*/ 8422 PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos) 8423 { 8424 PetscErrorCode ierr; 8425 8426 PetscFunctionBegin; 8427 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8428 PetscValidType(mat,1); 8429 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8430 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled"); 8431 if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8432 ierr = (*mat->ops->getinertia)(mat,nneg,nzero,npos);CHKERRQ(ierr); 8433 PetscFunctionReturn(0); 8434 } 8435 8436 /* ----------------------------------------------------------------*/ 8437 /*@C 8438 MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors 8439 8440 Neighbor-wise Collective on Mats 8441 8442 Input Parameters: 8443 + mat - the factored matrix 8444 - b - the right-hand-side vectors 8445 8446 Output Parameter: 8447 . x - the result vectors 8448 8449 Notes: 8450 The vectors b and x cannot be the same. I.e., one cannot 8451 call MatSolves(A,x,x). 8452 8453 Notes: 8454 Most users should employ the simplified KSP interface for linear solvers 8455 instead of working directly with matrix algebra routines such as this. 8456 See, e.g., KSPCreate(). 8457 8458 Level: developer 8459 8460 .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve() 8461 @*/ 8462 PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x) 8463 { 8464 PetscErrorCode ierr; 8465 8466 PetscFunctionBegin; 8467 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8468 PetscValidType(mat,1); 8469 if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors"); 8470 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix"); 8471 if (!mat->rmap->N && !mat->cmap->N) PetscFunctionReturn(0); 8472 8473 if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name); 8474 MatCheckPreallocated(mat,1); 8475 ierr = PetscLogEventBegin(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8476 ierr = (*mat->ops->solves)(mat,b,x);CHKERRQ(ierr); 8477 ierr = PetscLogEventEnd(MAT_Solves,mat,0,0,0);CHKERRQ(ierr); 8478 PetscFunctionReturn(0); 8479 } 8480 8481 /*@ 8482 MatIsSymmetric - Test whether a matrix is symmetric 8483 8484 Collective on Mat 8485 8486 Input Parameter: 8487 + A - the matrix to test 8488 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose) 8489 8490 Output Parameters: 8491 . flg - the result 8492 8493 Notes: 8494 For real numbers MatIsSymmetric() and MatIsHermitian() return identical results 8495 8496 Level: intermediate 8497 8498 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown() 8499 @*/ 8500 PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg) 8501 { 8502 PetscErrorCode ierr; 8503 8504 PetscFunctionBegin; 8505 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8506 PetscValidPointer(flg,2); 8507 8508 if (!A->symmetric_set) { 8509 if (!A->ops->issymmetric) { 8510 MatType mattype; 8511 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8512 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8513 } 8514 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8515 if (!tol) { 8516 A->symmetric_set = PETSC_TRUE; 8517 A->symmetric = *flg; 8518 if (A->symmetric) { 8519 A->structurally_symmetric_set = PETSC_TRUE; 8520 A->structurally_symmetric = PETSC_TRUE; 8521 } 8522 } 8523 } else if (A->symmetric) { 8524 *flg = PETSC_TRUE; 8525 } else if (!tol) { 8526 *flg = PETSC_FALSE; 8527 } else { 8528 if (!A->ops->issymmetric) { 8529 MatType mattype; 8530 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8531 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype); 8532 } 8533 ierr = (*A->ops->issymmetric)(A,tol,flg);CHKERRQ(ierr); 8534 } 8535 PetscFunctionReturn(0); 8536 } 8537 8538 /*@ 8539 MatIsHermitian - Test whether a matrix is Hermitian 8540 8541 Collective on Mat 8542 8543 Input Parameter: 8544 + A - the matrix to test 8545 - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian) 8546 8547 Output Parameters: 8548 . flg - the result 8549 8550 Level: intermediate 8551 8552 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), 8553 MatIsSymmetricKnown(), MatIsSymmetric() 8554 @*/ 8555 PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg) 8556 { 8557 PetscErrorCode ierr; 8558 8559 PetscFunctionBegin; 8560 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8561 PetscValidPointer(flg,2); 8562 8563 if (!A->hermitian_set) { 8564 if (!A->ops->ishermitian) { 8565 MatType mattype; 8566 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8567 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8568 } 8569 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8570 if (!tol) { 8571 A->hermitian_set = PETSC_TRUE; 8572 A->hermitian = *flg; 8573 if (A->hermitian) { 8574 A->structurally_symmetric_set = PETSC_TRUE; 8575 A->structurally_symmetric = PETSC_TRUE; 8576 } 8577 } 8578 } else if (A->hermitian) { 8579 *flg = PETSC_TRUE; 8580 } else if (!tol) { 8581 *flg = PETSC_FALSE; 8582 } else { 8583 if (!A->ops->ishermitian) { 8584 MatType mattype; 8585 ierr = MatGetType(A,&mattype);CHKERRQ(ierr); 8586 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype); 8587 } 8588 ierr = (*A->ops->ishermitian)(A,tol,flg);CHKERRQ(ierr); 8589 } 8590 PetscFunctionReturn(0); 8591 } 8592 8593 /*@ 8594 MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric. 8595 8596 Not Collective 8597 8598 Input Parameter: 8599 . A - the matrix to check 8600 8601 Output Parameters: 8602 + set - if the symmetric flag is set (this tells you if the next flag is valid) 8603 - flg - the result 8604 8605 Level: advanced 8606 8607 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric() 8608 if you want it explicitly checked 8609 8610 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8611 @*/ 8612 PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg) 8613 { 8614 PetscFunctionBegin; 8615 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8616 PetscValidPointer(set,2); 8617 PetscValidPointer(flg,3); 8618 if (A->symmetric_set) { 8619 *set = PETSC_TRUE; 8620 *flg = A->symmetric; 8621 } else { 8622 *set = PETSC_FALSE; 8623 } 8624 PetscFunctionReturn(0); 8625 } 8626 8627 /*@ 8628 MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian. 8629 8630 Not Collective 8631 8632 Input Parameter: 8633 . A - the matrix to check 8634 8635 Output Parameters: 8636 + set - if the hermitian flag is set (this tells you if the next flag is valid) 8637 - flg - the result 8638 8639 Level: advanced 8640 8641 Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian() 8642 if you want it explicitly checked 8643 8644 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric() 8645 @*/ 8646 PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg) 8647 { 8648 PetscFunctionBegin; 8649 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8650 PetscValidPointer(set,2); 8651 PetscValidPointer(flg,3); 8652 if (A->hermitian_set) { 8653 *set = PETSC_TRUE; 8654 *flg = A->hermitian; 8655 } else { 8656 *set = PETSC_FALSE; 8657 } 8658 PetscFunctionReturn(0); 8659 } 8660 8661 /*@ 8662 MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric 8663 8664 Collective on Mat 8665 8666 Input Parameter: 8667 . A - the matrix to test 8668 8669 Output Parameters: 8670 . flg - the result 8671 8672 Level: intermediate 8673 8674 .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption() 8675 @*/ 8676 PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg) 8677 { 8678 PetscErrorCode ierr; 8679 8680 PetscFunctionBegin; 8681 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 8682 PetscValidPointer(flg,2); 8683 if (!A->structurally_symmetric_set) { 8684 if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric"); 8685 ierr = (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);CHKERRQ(ierr); 8686 8687 A->structurally_symmetric_set = PETSC_TRUE; 8688 } 8689 *flg = A->structurally_symmetric; 8690 PetscFunctionReturn(0); 8691 } 8692 8693 /*@ 8694 MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need 8695 to be communicated to other processors during the MatAssemblyBegin/End() process 8696 8697 Not collective 8698 8699 Input Parameter: 8700 . vec - the vector 8701 8702 Output Parameters: 8703 + nstash - the size of the stash 8704 . reallocs - the number of additional mallocs incurred. 8705 . bnstash - the size of the block stash 8706 - breallocs - the number of additional mallocs incurred.in the block stash 8707 8708 Level: advanced 8709 8710 .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize() 8711 8712 @*/ 8713 PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs) 8714 { 8715 PetscErrorCode ierr; 8716 8717 PetscFunctionBegin; 8718 ierr = MatStashGetInfo_Private(&mat->stash,nstash,reallocs);CHKERRQ(ierr); 8719 ierr = MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);CHKERRQ(ierr); 8720 PetscFunctionReturn(0); 8721 } 8722 8723 /*@C 8724 MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same 8725 parallel layout 8726 8727 Collective on Mat 8728 8729 Input Parameter: 8730 . mat - the matrix 8731 8732 Output Parameter: 8733 + right - (optional) vector that the matrix can be multiplied against 8734 - left - (optional) vector that the matrix vector product can be stored in 8735 8736 Notes: 8737 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(). 8738 8739 Notes: 8740 These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed 8741 8742 Level: advanced 8743 8744 .seealso: MatCreate(), VecDestroy() 8745 @*/ 8746 PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left) 8747 { 8748 PetscErrorCode ierr; 8749 8750 PetscFunctionBegin; 8751 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8752 PetscValidType(mat,1); 8753 if (mat->ops->getvecs) { 8754 ierr = (*mat->ops->getvecs)(mat,right,left);CHKERRQ(ierr); 8755 } else { 8756 PetscInt rbs,cbs; 8757 ierr = MatGetBlockSizes(mat,&rbs,&cbs);CHKERRQ(ierr); 8758 if (right) { 8759 if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup"); 8760 ierr = VecCreate(PetscObjectComm((PetscObject)mat),right);CHKERRQ(ierr); 8761 ierr = VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8762 ierr = VecSetBlockSize(*right,cbs);CHKERRQ(ierr); 8763 ierr = VecSetType(*right,mat->defaultvectype);CHKERRQ(ierr); 8764 ierr = PetscLayoutReference(mat->cmap,&(*right)->map);CHKERRQ(ierr); 8765 } 8766 if (left) { 8767 if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup"); 8768 ierr = VecCreate(PetscObjectComm((PetscObject)mat),left);CHKERRQ(ierr); 8769 ierr = VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);CHKERRQ(ierr); 8770 ierr = VecSetBlockSize(*left,rbs);CHKERRQ(ierr); 8771 ierr = VecSetType(*left,mat->defaultvectype);CHKERRQ(ierr); 8772 ierr = PetscLayoutReference(mat->rmap,&(*left)->map);CHKERRQ(ierr); 8773 } 8774 } 8775 PetscFunctionReturn(0); 8776 } 8777 8778 /*@C 8779 MatFactorInfoInitialize - Initializes a MatFactorInfo data structure 8780 with default values. 8781 8782 Not Collective 8783 8784 Input Parameters: 8785 . info - the MatFactorInfo data structure 8786 8787 8788 Notes: 8789 The solvers are generally used through the KSP and PC objects, for example 8790 PCLU, PCILU, PCCHOLESKY, PCICC 8791 8792 Level: developer 8793 8794 .seealso: MatFactorInfo 8795 8796 Developer Note: fortran interface is not autogenerated as the f90 8797 interface defintion cannot be generated correctly [due to MatFactorInfo] 8798 8799 @*/ 8800 8801 PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info) 8802 { 8803 PetscErrorCode ierr; 8804 8805 PetscFunctionBegin; 8806 ierr = PetscMemzero(info,sizeof(MatFactorInfo));CHKERRQ(ierr); 8807 PetscFunctionReturn(0); 8808 } 8809 8810 /*@ 8811 MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed 8812 8813 Collective on Mat 8814 8815 Input Parameters: 8816 + mat - the factored matrix 8817 - is - the index set defining the Schur indices (0-based) 8818 8819 Notes: 8820 Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system. 8821 8822 You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call. 8823 8824 Level: developer 8825 8826 .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(), 8827 MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement() 8828 8829 @*/ 8830 PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is) 8831 { 8832 PetscErrorCode ierr,(*f)(Mat,IS); 8833 8834 PetscFunctionBegin; 8835 PetscValidType(mat,1); 8836 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 8837 PetscValidType(is,2); 8838 PetscValidHeaderSpecific(is,IS_CLASSID,2); 8839 PetscCheckSameComm(mat,1,is,2); 8840 if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix"); 8841 ierr = PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);CHKERRQ(ierr); 8842 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"); 8843 if (mat->schur) { 8844 ierr = MatDestroy(&mat->schur);CHKERRQ(ierr); 8845 } 8846 ierr = (*f)(mat,is);CHKERRQ(ierr); 8847 if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created"); 8848 ierr = MatFactorSetUpInPlaceSchur_Private(mat);CHKERRQ(ierr); 8849 PetscFunctionReturn(0); 8850 } 8851 8852 /*@ 8853 MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step 8854 8855 Logically Collective on Mat 8856 8857 Input Parameters: 8858 + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface 8859 . S - location where to return the Schur complement, can be NULL 8860 - status - the status of the Schur complement matrix, can be NULL 8861 8862 Notes: 8863 You must call MatFactorSetSchurIS() before calling this routine. 8864 8865 The routine provides a copy of the Schur matrix stored within the solver data structures. 8866 The caller must destroy the object when it is no longer needed. 8867 If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse. 8868 8869 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) 8870 8871 Developer Notes: 8872 The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc 8873 matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix. 8874 8875 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 8876 8877 Level: advanced 8878 8879 References: 8880 8881 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus 8882 @*/ 8883 PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 8884 { 8885 PetscErrorCode ierr; 8886 8887 PetscFunctionBegin; 8888 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8889 if (S) PetscValidPointer(S,2); 8890 if (status) PetscValidPointer(status,3); 8891 if (S) { 8892 PetscErrorCode (*f)(Mat,Mat*); 8893 8894 ierr = PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);CHKERRQ(ierr); 8895 if (f) { 8896 ierr = (*f)(F,S);CHKERRQ(ierr); 8897 } else { 8898 ierr = MatDuplicate(F->schur,MAT_COPY_VALUES,S);CHKERRQ(ierr); 8899 } 8900 } 8901 if (status) *status = F->schur_status; 8902 PetscFunctionReturn(0); 8903 } 8904 8905 /*@ 8906 MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix 8907 8908 Logically Collective on Mat 8909 8910 Input Parameters: 8911 + F - the factored matrix obtained by calling MatGetFactor() 8912 . *S - location where to return the Schur complement, can be NULL 8913 - status - the status of the Schur complement matrix, can be NULL 8914 8915 Notes: 8916 You must call MatFactorSetSchurIS() before calling this routine. 8917 8918 Schur complement mode is currently implemented for sequential matrices. 8919 The routine returns a the Schur Complement stored within the data strutures of the solver. 8920 If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement. 8921 The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed. 8922 8923 Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix 8924 8925 See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements. 8926 8927 Level: advanced 8928 8929 References: 8930 8931 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 8932 @*/ 8933 PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status) 8934 { 8935 PetscFunctionBegin; 8936 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8937 if (S) PetscValidPointer(S,2); 8938 if (status) PetscValidPointer(status,3); 8939 if (S) *S = F->schur; 8940 if (status) *status = F->schur_status; 8941 PetscFunctionReturn(0); 8942 } 8943 8944 /*@ 8945 MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement 8946 8947 Logically Collective on Mat 8948 8949 Input Parameters: 8950 + F - the factored matrix obtained by calling MatGetFactor() 8951 . *S - location where the Schur complement is stored 8952 - status - the status of the Schur complement matrix (see MatFactorSchurStatus) 8953 8954 Notes: 8955 8956 Level: advanced 8957 8958 References: 8959 8960 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus 8961 @*/ 8962 PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status) 8963 { 8964 PetscErrorCode ierr; 8965 8966 PetscFunctionBegin; 8967 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 8968 if (S) { 8969 PetscValidHeaderSpecific(*S,MAT_CLASSID,2); 8970 *S = NULL; 8971 } 8972 F->schur_status = status; 8973 ierr = MatFactorUpdateSchurStatus_Private(F);CHKERRQ(ierr); 8974 PetscFunctionReturn(0); 8975 } 8976 8977 /*@ 8978 MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step 8979 8980 Logically Collective on Mat 8981 8982 Input Parameters: 8983 + F - the factored matrix obtained by calling MatGetFactor() 8984 . rhs - location where the right hand side of the Schur complement system is stored 8985 - sol - location where the solution of the Schur complement system has to be returned 8986 8987 Notes: 8988 The sizes of the vectors should match the size of the Schur complement 8989 8990 Must be called after MatFactorSetSchurIS() 8991 8992 Level: advanced 8993 8994 References: 8995 8996 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement() 8997 @*/ 8998 PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol) 8999 { 9000 PetscErrorCode ierr; 9001 9002 PetscFunctionBegin; 9003 PetscValidType(F,1); 9004 PetscValidType(rhs,2); 9005 PetscValidType(sol,3); 9006 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9007 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9008 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9009 PetscCheckSameComm(F,1,rhs,2); 9010 PetscCheckSameComm(F,1,sol,3); 9011 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9012 switch (F->schur_status) { 9013 case MAT_FACTOR_SCHUR_FACTORED: 9014 ierr = MatSolveTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9015 break; 9016 case MAT_FACTOR_SCHUR_INVERTED: 9017 ierr = MatMultTranspose(F->schur,rhs,sol);CHKERRQ(ierr); 9018 break; 9019 default: 9020 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9021 break; 9022 } 9023 PetscFunctionReturn(0); 9024 } 9025 9026 /*@ 9027 MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step 9028 9029 Logically Collective on Mat 9030 9031 Input Parameters: 9032 + F - the factored matrix obtained by calling MatGetFactor() 9033 . rhs - location where the right hand side of the Schur complement system is stored 9034 - sol - location where the solution of the Schur complement system has to be returned 9035 9036 Notes: 9037 The sizes of the vectors should match the size of the Schur complement 9038 9039 Must be called after MatFactorSetSchurIS() 9040 9041 Level: advanced 9042 9043 References: 9044 9045 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose() 9046 @*/ 9047 PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol) 9048 { 9049 PetscErrorCode ierr; 9050 9051 PetscFunctionBegin; 9052 PetscValidType(F,1); 9053 PetscValidType(rhs,2); 9054 PetscValidType(sol,3); 9055 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9056 PetscValidHeaderSpecific(rhs,VEC_CLASSID,2); 9057 PetscValidHeaderSpecific(sol,VEC_CLASSID,3); 9058 PetscCheckSameComm(F,1,rhs,2); 9059 PetscCheckSameComm(F,1,sol,3); 9060 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9061 switch (F->schur_status) { 9062 case MAT_FACTOR_SCHUR_FACTORED: 9063 ierr = MatSolve(F->schur,rhs,sol);CHKERRQ(ierr); 9064 break; 9065 case MAT_FACTOR_SCHUR_INVERTED: 9066 ierr = MatMult(F->schur,rhs,sol);CHKERRQ(ierr); 9067 break; 9068 default: 9069 SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status); 9070 break; 9071 } 9072 PetscFunctionReturn(0); 9073 } 9074 9075 /*@ 9076 MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step 9077 9078 Logically Collective on Mat 9079 9080 Input Parameters: 9081 + F - the factored matrix obtained by calling MatGetFactor() 9082 9083 Notes: 9084 Must be called after MatFactorSetSchurIS(). 9085 9086 Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it. 9087 9088 Level: advanced 9089 9090 References: 9091 9092 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement() 9093 @*/ 9094 PetscErrorCode MatFactorInvertSchurComplement(Mat F) 9095 { 9096 PetscErrorCode ierr; 9097 9098 PetscFunctionBegin; 9099 PetscValidType(F,1); 9100 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9101 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) PetscFunctionReturn(0); 9102 ierr = MatFactorFactorizeSchurComplement(F);CHKERRQ(ierr); 9103 ierr = MatFactorInvertSchurComplement_Private(F);CHKERRQ(ierr); 9104 F->schur_status = MAT_FACTOR_SCHUR_INVERTED; 9105 PetscFunctionReturn(0); 9106 } 9107 9108 /*@ 9109 MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step 9110 9111 Logically Collective on Mat 9112 9113 Input Parameters: 9114 + F - the factored matrix obtained by calling MatGetFactor() 9115 9116 Notes: 9117 Must be called after MatFactorSetSchurIS(). 9118 9119 Level: advanced 9120 9121 References: 9122 9123 .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement() 9124 @*/ 9125 PetscErrorCode MatFactorFactorizeSchurComplement(Mat F) 9126 { 9127 PetscErrorCode ierr; 9128 9129 PetscFunctionBegin; 9130 PetscValidType(F,1); 9131 PetscValidHeaderSpecific(F,MAT_CLASSID,1); 9132 if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) PetscFunctionReturn(0); 9133 ierr = MatFactorFactorizeSchurComplement_Private(F);CHKERRQ(ierr); 9134 F->schur_status = MAT_FACTOR_SCHUR_FACTORED; 9135 PetscFunctionReturn(0); 9136 } 9137 9138 static PetscErrorCode MatPtAP_Basic(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9139 { 9140 Mat AP; 9141 PetscErrorCode ierr; 9142 9143 PetscFunctionBegin; 9144 ierr = PetscInfo2(A,"Mat types %s and %s using basic PtAP\n",((PetscObject)A)->type_name,((PetscObject)P)->type_name);CHKERRQ(ierr); 9145 ierr = MatMatMult(A,P,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AP);CHKERRQ(ierr); 9146 ierr = MatTransposeMatMult(P,AP,scall,fill,C);CHKERRQ(ierr); 9147 ierr = MatDestroy(&AP);CHKERRQ(ierr); 9148 PetscFunctionReturn(0); 9149 } 9150 9151 /*@ 9152 MatPtAP - Creates the matrix product C = P^T * A * P 9153 9154 Neighbor-wise Collective on Mat 9155 9156 Input Parameters: 9157 + A - the matrix 9158 . P - the projection matrix 9159 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9160 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate 9161 if the result is a dense matrix this is irrelevent 9162 9163 Output Parameters: 9164 . C - the product matrix 9165 9166 Notes: 9167 C will be created and must be destroyed by the user with MatDestroy(). 9168 9169 For matrix types without special implementation the function fallbacks to MatMatMult() followed by MatTransposeMatMult(). 9170 9171 Level: intermediate 9172 9173 .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt() 9174 @*/ 9175 PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C) 9176 { 9177 PetscErrorCode ierr; 9178 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9179 PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*); 9180 PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9181 PetscBool sametype; 9182 9183 PetscFunctionBegin; 9184 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9185 PetscValidType(A,1); 9186 MatCheckPreallocated(A,1); 9187 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9188 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9189 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9190 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9191 PetscValidType(P,2); 9192 MatCheckPreallocated(P,2); 9193 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9194 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9195 9196 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); 9197 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); 9198 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9199 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9200 9201 if (scall == MAT_REUSE_MATRIX) { 9202 PetscValidPointer(*C,5); 9203 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9204 9205 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9206 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9207 if ((*C)->ops->ptapnumeric) { 9208 ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 9209 } else { 9210 ierr = MatPtAP_Basic(A,P,scall,fill,C); 9211 } 9212 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9213 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9214 PetscFunctionReturn(0); 9215 } 9216 9217 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9218 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9219 9220 fA = A->ops->ptap; 9221 fP = P->ops->ptap; 9222 ierr = PetscStrcmp(((PetscObject)A)->type_name,((PetscObject)P)->type_name,&sametype);CHKERRQ(ierr); 9223 if (fP == fA && sametype) { 9224 ptap = fA; 9225 } else { 9226 /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */ 9227 char ptapname[256]; 9228 ierr = PetscStrncpy(ptapname,"MatPtAP_",sizeof(ptapname));CHKERRQ(ierr); 9229 ierr = PetscStrlcat(ptapname,((PetscObject)A)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9230 ierr = PetscStrlcat(ptapname,"_",sizeof(ptapname));CHKERRQ(ierr); 9231 ierr = PetscStrlcat(ptapname,((PetscObject)P)->type_name,sizeof(ptapname));CHKERRQ(ierr); 9232 ierr = PetscStrlcat(ptapname,"_C",sizeof(ptapname));CHKERRQ(ierr); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */ 9233 ierr = PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);CHKERRQ(ierr); 9234 } 9235 9236 if (!ptap) ptap = MatPtAP_Basic; 9237 ierr = PetscLogEventBegin(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9238 ierr = (*ptap)(A,P,scall,fill,C);CHKERRQ(ierr); 9239 ierr = PetscLogEventEnd(MAT_PtAP,A,P,0,0);CHKERRQ(ierr); 9240 if (A->symmetric_set && A->symmetric) { 9241 ierr = MatSetOption(*C,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 9242 } 9243 PetscFunctionReturn(0); 9244 } 9245 9246 /*@ 9247 MatPtAPNumeric - Computes the matrix product C = P^T * A * P 9248 9249 Neighbor-wise Collective on Mat 9250 9251 Input Parameters: 9252 + A - the matrix 9253 - P - the projection matrix 9254 9255 Output Parameters: 9256 . C - the product matrix 9257 9258 Notes: 9259 C must have been created by calling MatPtAPSymbolic and must be destroyed by 9260 the user using MatDeatroy(). 9261 9262 This routine is currently only implemented for pairs of AIJ matrices and classes 9263 which inherit from AIJ. C will be of type MATAIJ. 9264 9265 Level: intermediate 9266 9267 .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric() 9268 @*/ 9269 PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C) 9270 { 9271 PetscErrorCode ierr; 9272 9273 PetscFunctionBegin; 9274 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9275 PetscValidType(A,1); 9276 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9277 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9278 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9279 PetscValidType(P,2); 9280 MatCheckPreallocated(P,2); 9281 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9282 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9283 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9284 PetscValidType(C,3); 9285 MatCheckPreallocated(C,3); 9286 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9287 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); 9288 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); 9289 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); 9290 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); 9291 MatCheckPreallocated(A,1); 9292 9293 if (!C->ops->ptapnumeric) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"MatPtAPNumeric implementation is missing. You should call MatPtAPSymbolic first"); 9294 ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9295 ierr = (*C->ops->ptapnumeric)(A,P,C);CHKERRQ(ierr); 9296 ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 9297 PetscFunctionReturn(0); 9298 } 9299 9300 /*@ 9301 MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P 9302 9303 Neighbor-wise Collective on Mat 9304 9305 Input Parameters: 9306 + A - the matrix 9307 - P - the projection matrix 9308 9309 Output Parameters: 9310 . C - the (i,j) structure of the product matrix 9311 9312 Notes: 9313 C will be created and must be destroyed by the user with MatDestroy(). 9314 9315 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9316 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9317 this (i,j) structure by calling MatPtAPNumeric(). 9318 9319 Level: intermediate 9320 9321 .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic() 9322 @*/ 9323 PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C) 9324 { 9325 PetscErrorCode ierr; 9326 9327 PetscFunctionBegin; 9328 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9329 PetscValidType(A,1); 9330 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9331 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9332 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9333 PetscValidHeaderSpecific(P,MAT_CLASSID,2); 9334 PetscValidType(P,2); 9335 MatCheckPreallocated(P,2); 9336 if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9337 if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9338 PetscValidPointer(C,3); 9339 9340 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); 9341 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); 9342 MatCheckPreallocated(A,1); 9343 9344 if (!A->ops->ptapsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatType %s",((PetscObject)A)->type_name); 9345 ierr = PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9346 ierr = (*A->ops->ptapsymbolic)(A,P,fill,C);CHKERRQ(ierr); 9347 ierr = PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);CHKERRQ(ierr); 9348 9349 /* ierr = MatSetBlockSize(*C,A->rmap->bs);CHKERRQ(ierr); NO! this is not always true -ma */ 9350 PetscFunctionReturn(0); 9351 } 9352 9353 /*@ 9354 MatRARt - Creates the matrix product C = R * A * R^T 9355 9356 Neighbor-wise Collective on Mat 9357 9358 Input Parameters: 9359 + A - the matrix 9360 . R - the projection matrix 9361 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9362 - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate 9363 if the result is a dense matrix this is irrelevent 9364 9365 Output Parameters: 9366 . C - the product matrix 9367 9368 Notes: 9369 C will be created and must be destroyed by the user with MatDestroy(). 9370 9371 This routine is currently only implemented for pairs of AIJ matrices and classes 9372 which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes, 9373 parallel MatRARt is implemented via explicit transpose of R, which could be very expensive. 9374 We recommend using MatPtAP(). 9375 9376 Level: intermediate 9377 9378 .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP() 9379 @*/ 9380 PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 9381 { 9382 PetscErrorCode ierr; 9383 9384 PetscFunctionBegin; 9385 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9386 PetscValidType(A,1); 9387 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9388 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9389 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9390 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9391 PetscValidType(R,2); 9392 MatCheckPreallocated(R,2); 9393 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9394 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9395 PetscValidPointer(C,3); 9396 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); 9397 9398 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9399 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9400 MatCheckPreallocated(A,1); 9401 9402 if (!A->ops->rart) { 9403 Mat Rt; 9404 ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 9405 ierr = MatMatMatMult(R,A,Rt,scall,fill,C);CHKERRQ(ierr); 9406 ierr = MatDestroy(&Rt);CHKERRQ(ierr); 9407 PetscFunctionReturn(0); 9408 } 9409 ierr = PetscLogEventBegin(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9410 ierr = (*A->ops->rart)(A,R,scall,fill,C);CHKERRQ(ierr); 9411 ierr = PetscLogEventEnd(MAT_RARt,A,R,0,0);CHKERRQ(ierr); 9412 PetscFunctionReturn(0); 9413 } 9414 9415 /*@ 9416 MatRARtNumeric - Computes the matrix product C = R * A * R^T 9417 9418 Neighbor-wise Collective on Mat 9419 9420 Input Parameters: 9421 + A - the matrix 9422 - R - the projection matrix 9423 9424 Output Parameters: 9425 . C - the product matrix 9426 9427 Notes: 9428 C must have been created by calling MatRARtSymbolic and must be destroyed by 9429 the user using MatDestroy(). 9430 9431 This routine is currently only implemented for pairs of AIJ matrices and classes 9432 which inherit from AIJ. C will be of type MATAIJ. 9433 9434 Level: intermediate 9435 9436 .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric() 9437 @*/ 9438 PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C) 9439 { 9440 PetscErrorCode ierr; 9441 9442 PetscFunctionBegin; 9443 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9444 PetscValidType(A,1); 9445 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9446 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9447 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9448 PetscValidType(R,2); 9449 MatCheckPreallocated(R,2); 9450 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9451 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9452 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9453 PetscValidType(C,3); 9454 MatCheckPreallocated(C,3); 9455 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9456 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); 9457 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); 9458 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); 9459 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); 9460 MatCheckPreallocated(A,1); 9461 9462 ierr = PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9463 ierr = (*A->ops->rartnumeric)(A,R,C);CHKERRQ(ierr); 9464 ierr = PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);CHKERRQ(ierr); 9465 PetscFunctionReturn(0); 9466 } 9467 9468 /*@ 9469 MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T 9470 9471 Neighbor-wise Collective on Mat 9472 9473 Input Parameters: 9474 + A - the matrix 9475 - R - the projection matrix 9476 9477 Output Parameters: 9478 . C - the (i,j) structure of the product matrix 9479 9480 Notes: 9481 C will be created and must be destroyed by the user with MatDestroy(). 9482 9483 This routine is currently only implemented for pairs of SeqAIJ matrices and classes 9484 which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using 9485 this (i,j) structure by calling MatRARtNumeric(). 9486 9487 Level: intermediate 9488 9489 .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic() 9490 @*/ 9491 PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C) 9492 { 9493 PetscErrorCode ierr; 9494 9495 PetscFunctionBegin; 9496 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9497 PetscValidType(A,1); 9498 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9499 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9500 if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9501 PetscValidHeaderSpecific(R,MAT_CLASSID,2); 9502 PetscValidType(R,2); 9503 MatCheckPreallocated(R,2); 9504 if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9505 if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9506 PetscValidPointer(C,3); 9507 9508 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); 9509 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); 9510 MatCheckPreallocated(A,1); 9511 ierr = PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9512 ierr = (*A->ops->rartsymbolic)(A,R,fill,C);CHKERRQ(ierr); 9513 ierr = PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);CHKERRQ(ierr); 9514 9515 ierr = MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));CHKERRQ(ierr); 9516 PetscFunctionReturn(0); 9517 } 9518 9519 /*@ 9520 MatMatMult - Performs Matrix-Matrix Multiplication C=A*B. 9521 9522 Neighbor-wise Collective on Mat 9523 9524 Input Parameters: 9525 + A - the left matrix 9526 . B - the right matrix 9527 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9528 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate 9529 if the result is a dense matrix this is irrelevent 9530 9531 Output Parameters: 9532 . C - the product matrix 9533 9534 Notes: 9535 Unless scall is MAT_REUSE_MATRIX C will be created. 9536 9537 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 9538 call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic() 9539 9540 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9541 actually needed. 9542 9543 If you have many matrices with the same non-zero structure to multiply, you 9544 should either 9545 $ 1) use MAT_REUSE_MATRIX in all calls but the first or 9546 $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed 9547 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 9548 with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse. 9549 9550 Level: intermediate 9551 9552 .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP() 9553 @*/ 9554 PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9555 { 9556 PetscErrorCode ierr; 9557 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9558 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9559 PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9560 Mat T; 9561 PetscBool istrans; 9562 9563 PetscFunctionBegin; 9564 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9565 PetscValidType(A,1); 9566 MatCheckPreallocated(A,1); 9567 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9568 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9569 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9570 PetscValidType(B,2); 9571 MatCheckPreallocated(B,2); 9572 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9573 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9574 PetscValidPointer(C,3); 9575 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9576 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); 9577 ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9578 if (istrans) { 9579 ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 9580 ierr = MatTransposeMatMult(T,B,scall,fill,C);CHKERRQ(ierr); 9581 PetscFunctionReturn(0); 9582 } else { 9583 ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9584 if (istrans) { 9585 ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr); 9586 ierr = MatMatTransposeMult(A,T,scall,fill,C);CHKERRQ(ierr); 9587 PetscFunctionReturn(0); 9588 } 9589 } 9590 if (scall == MAT_REUSE_MATRIX) { 9591 PetscValidPointer(*C,5); 9592 PetscValidHeaderSpecific(*C,MAT_CLASSID,5); 9593 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9594 ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9595 ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr); 9596 ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 9597 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9598 PetscFunctionReturn(0); 9599 } 9600 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9601 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9602 9603 fA = A->ops->matmult; 9604 fB = B->ops->matmult; 9605 if (fB == fA) { 9606 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name); 9607 mult = fB; 9608 } else { 9609 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9610 char multname[256]; 9611 ierr = PetscStrncpy(multname,"MatMatMult_",sizeof(multname));CHKERRQ(ierr); 9612 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9613 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9614 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9615 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9616 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9617 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); 9618 } 9619 ierr = PetscLogEventBegin(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9620 ierr = (*mult)(A,B,scall,fill,C);CHKERRQ(ierr); 9621 ierr = PetscLogEventEnd(MAT_MatMult,A,B,0,0);CHKERRQ(ierr); 9622 PetscFunctionReturn(0); 9623 } 9624 9625 /*@ 9626 MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure 9627 of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric(). 9628 9629 Neighbor-wise Collective on Mat 9630 9631 Input Parameters: 9632 + A - the left matrix 9633 . B - the right matrix 9634 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate, 9635 if C is a dense matrix this is irrelevent 9636 9637 Output Parameters: 9638 . C - the product matrix 9639 9640 Notes: 9641 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9642 actually needed. 9643 9644 This routine is currently implemented for 9645 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ 9646 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9647 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9648 9649 Level: intermediate 9650 9651 Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, https://arxiv.org/abs/1006.4173 9652 We should incorporate them into PETSc. 9653 9654 .seealso: MatMatMult(), MatMatMultNumeric() 9655 @*/ 9656 PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C) 9657 { 9658 PetscErrorCode ierr; 9659 PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*); 9660 PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*); 9661 PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL; 9662 9663 PetscFunctionBegin; 9664 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9665 PetscValidType(A,1); 9666 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9667 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9668 9669 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9670 PetscValidType(B,2); 9671 MatCheckPreallocated(B,2); 9672 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9673 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9674 PetscValidPointer(C,3); 9675 9676 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); 9677 if (fill == PETSC_DEFAULT) fill = 2.0; 9678 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9679 MatCheckPreallocated(A,1); 9680 9681 Asymbolic = A->ops->matmultsymbolic; 9682 Bsymbolic = B->ops->matmultsymbolic; 9683 if (Asymbolic == Bsymbolic) { 9684 if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name); 9685 symbolic = Bsymbolic; 9686 } else { /* dispatch based on the type of A and B */ 9687 char symbolicname[256]; 9688 ierr = PetscStrncpy(symbolicname,"MatMatMultSymbolic_",sizeof(symbolicname));CHKERRQ(ierr); 9689 ierr = PetscStrlcat(symbolicname,((PetscObject)A)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9690 ierr = PetscStrlcat(symbolicname,"_",sizeof(symbolicname));CHKERRQ(ierr); 9691 ierr = PetscStrlcat(symbolicname,((PetscObject)B)->type_name,sizeof(symbolicname));CHKERRQ(ierr); 9692 ierr = PetscStrlcat(symbolicname,"_C",sizeof(symbolicname));CHKERRQ(ierr); 9693 ierr = PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);CHKERRQ(ierr); 9694 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); 9695 } 9696 ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9697 ierr = (*symbolic)(A,B,fill,C);CHKERRQ(ierr); 9698 ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9699 PetscFunctionReturn(0); 9700 } 9701 9702 /*@ 9703 MatMatMultNumeric - Performs the numeric matrix-matrix product. 9704 Call this routine after first calling MatMatMultSymbolic(). 9705 9706 Neighbor-wise Collective on Mat 9707 9708 Input Parameters: 9709 + A - the left matrix 9710 - B - the right matrix 9711 9712 Output Parameters: 9713 . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult(). 9714 9715 Notes: 9716 C must have been created with MatMatMultSymbolic(). 9717 9718 This routine is currently implemented for 9719 - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ. 9720 - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense. 9721 - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense. 9722 9723 Level: intermediate 9724 9725 .seealso: MatMatMult(), MatMatMultSymbolic() 9726 @*/ 9727 PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C) 9728 { 9729 PetscErrorCode ierr; 9730 9731 PetscFunctionBegin; 9732 ierr = MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);CHKERRQ(ierr); 9733 PetscFunctionReturn(0); 9734 } 9735 9736 /*@ 9737 MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T. 9738 9739 Neighbor-wise Collective on Mat 9740 9741 Input Parameters: 9742 + A - the left matrix 9743 . B - the right matrix 9744 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9745 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9746 9747 Output Parameters: 9748 . C - the product matrix 9749 9750 Notes: 9751 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9752 9753 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9754 9755 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9756 actually needed. 9757 9758 This routine is currently only implemented for pairs of SeqAIJ matrices, for the SeqDense class, 9759 and for pairs of MPIDense matrices. 9760 9761 Options Database Keys: 9762 + -matmattransmult_mpidense_mpidense_via {allgatherv,cyclic} - Choose between algorthims for MPIDense matrices: the 9763 first redundantly copies the transposed B matrix on each process and requiers O(log P) communication complexity; 9764 the second never stores more than one portion of the B matrix at a time by requires O(P) communication complexity. 9765 9766 Level: intermediate 9767 9768 .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP() 9769 @*/ 9770 PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9771 { 9772 PetscErrorCode ierr; 9773 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9774 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9775 Mat T; 9776 PetscBool istrans; 9777 9778 PetscFunctionBegin; 9779 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9780 PetscValidType(A,1); 9781 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9782 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9783 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9784 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9785 PetscValidType(B,2); 9786 MatCheckPreallocated(B,2); 9787 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9788 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9789 PetscValidPointer(C,3); 9790 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); 9791 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9792 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9793 MatCheckPreallocated(A,1); 9794 9795 ierr = PetscObjectTypeCompare((PetscObject)B,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9796 if (istrans) { 9797 ierr = MatTransposeGetMat(B,&T);CHKERRQ(ierr); 9798 ierr = MatMatMult(A,T,scall,fill,C);CHKERRQ(ierr); 9799 PetscFunctionReturn(0); 9800 } 9801 fA = A->ops->mattransposemult; 9802 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name); 9803 fB = B->ops->mattransposemult; 9804 if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name); 9805 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); 9806 9807 ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9808 if (scall == MAT_INITIAL_MATRIX) { 9809 ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9810 ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr); 9811 ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 9812 } 9813 ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9814 ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr); 9815 ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 9816 ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr); 9817 PetscFunctionReturn(0); 9818 } 9819 9820 /*@ 9821 MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B. 9822 9823 Neighbor-wise Collective on Mat 9824 9825 Input Parameters: 9826 + A - the left matrix 9827 . B - the right matrix 9828 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9829 - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known 9830 9831 Output Parameters: 9832 . C - the product matrix 9833 9834 Notes: 9835 C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy(). 9836 9837 MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call 9838 9839 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9840 actually needed. 9841 9842 This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes 9843 which inherit from SeqAIJ. C will be of same type as the input matrices. 9844 9845 Level: intermediate 9846 9847 .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP() 9848 @*/ 9849 PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 9850 { 9851 PetscErrorCode ierr; 9852 PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*); 9853 PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*); 9854 PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL; 9855 Mat T; 9856 PetscBool istrans; 9857 9858 PetscFunctionBegin; 9859 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9860 PetscValidType(A,1); 9861 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9862 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9863 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9864 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9865 PetscValidType(B,2); 9866 MatCheckPreallocated(B,2); 9867 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9868 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9869 PetscValidPointer(C,3); 9870 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); 9871 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9872 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill); 9873 MatCheckPreallocated(A,1); 9874 9875 ierr = PetscObjectTypeCompare((PetscObject)A,MATTRANSPOSEMAT,&istrans);CHKERRQ(ierr); 9876 if (istrans) { 9877 ierr = MatTransposeGetMat(A,&T);CHKERRQ(ierr); 9878 ierr = MatMatMult(T,B,scall,fill,C);CHKERRQ(ierr); 9879 PetscFunctionReturn(0); 9880 } 9881 fA = A->ops->transposematmult; 9882 fB = B->ops->transposematmult; 9883 if (fB==fA) { 9884 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9885 transposematmult = fA; 9886 } else { 9887 /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */ 9888 char multname[256]; 9889 ierr = PetscStrncpy(multname,"MatTransposeMatMult_",sizeof(multname));CHKERRQ(ierr); 9890 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9891 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9892 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9893 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */ 9894 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr); 9895 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); 9896 } 9897 ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9898 ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr); 9899 ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr); 9900 PetscFunctionReturn(0); 9901 } 9902 9903 /*@ 9904 MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C. 9905 9906 Neighbor-wise Collective on Mat 9907 9908 Input Parameters: 9909 + A - the left matrix 9910 . B - the middle matrix 9911 . C - the right matrix 9912 . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 9913 - 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 9914 if the result is a dense matrix this is irrelevent 9915 9916 Output Parameters: 9917 . D - the product matrix 9918 9919 Notes: 9920 Unless scall is MAT_REUSE_MATRIX D will be created. 9921 9922 MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call 9923 9924 To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value 9925 actually needed. 9926 9927 If you have many matrices with the same non-zero structure to multiply, you 9928 should use MAT_REUSE_MATRIX in all calls but the first or 9929 9930 Level: intermediate 9931 9932 .seealso: MatMatMult, MatPtAP() 9933 @*/ 9934 PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 9935 { 9936 PetscErrorCode ierr; 9937 PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9938 PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9939 PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 9940 PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL; 9941 9942 PetscFunctionBegin; 9943 PetscValidHeaderSpecific(A,MAT_CLASSID,1); 9944 PetscValidType(A,1); 9945 MatCheckPreallocated(A,1); 9946 if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 9947 if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9948 if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9949 PetscValidHeaderSpecific(B,MAT_CLASSID,2); 9950 PetscValidType(B,2); 9951 MatCheckPreallocated(B,2); 9952 if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9953 if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9954 PetscValidHeaderSpecific(C,MAT_CLASSID,3); 9955 PetscValidPointer(C,3); 9956 MatCheckPreallocated(C,3); 9957 if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 9958 if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 9959 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); 9960 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); 9961 if (scall == MAT_REUSE_MATRIX) { 9962 PetscValidPointer(*D,6); 9963 PetscValidHeaderSpecific(*D,MAT_CLASSID,6); 9964 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9965 ierr = (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9966 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9967 PetscFunctionReturn(0); 9968 } 9969 if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0; 9970 if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill); 9971 9972 fA = A->ops->matmatmult; 9973 fB = B->ops->matmatmult; 9974 fC = C->ops->matmatmult; 9975 if (fA == fB && fA == fC) { 9976 if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name); 9977 mult = fA; 9978 } else { 9979 /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */ 9980 char multname[256]; 9981 ierr = PetscStrncpy(multname,"MatMatMatMult_",sizeof(multname));CHKERRQ(ierr); 9982 ierr = PetscStrlcat(multname,((PetscObject)A)->type_name,sizeof(multname));CHKERRQ(ierr); 9983 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9984 ierr = PetscStrlcat(multname,((PetscObject)B)->type_name,sizeof(multname));CHKERRQ(ierr); 9985 ierr = PetscStrlcat(multname,"_",sizeof(multname));CHKERRQ(ierr); 9986 ierr = PetscStrlcat(multname,((PetscObject)C)->type_name,sizeof(multname));CHKERRQ(ierr); 9987 ierr = PetscStrlcat(multname,"_C",sizeof(multname));CHKERRQ(ierr); 9988 ierr = PetscObjectQueryFunction((PetscObject)B,multname,&mult);CHKERRQ(ierr); 9989 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); 9990 } 9991 ierr = PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9992 ierr = (*mult)(A,B,C,scall,fill,D);CHKERRQ(ierr); 9993 ierr = PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);CHKERRQ(ierr); 9994 PetscFunctionReturn(0); 9995 } 9996 9997 /*@ 9998 MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators. 9999 10000 Collective on Mat 10001 10002 Input Parameters: 10003 + mat - the matrix 10004 . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices) 10005 . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used) 10006 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10007 10008 Output Parameter: 10009 . matredundant - redundant matrix 10010 10011 Notes: 10012 MAT_REUSE_MATRIX can only be used when the nonzero structure of the 10013 original matrix has not changed from that last call to MatCreateRedundantMatrix(). 10014 10015 This routine creates the duplicated matrices in subcommunicators; you should NOT create them before 10016 calling it. 10017 10018 Level: advanced 10019 10020 10021 .seealso: MatDestroy() 10022 @*/ 10023 PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant) 10024 { 10025 PetscErrorCode ierr; 10026 MPI_Comm comm; 10027 PetscMPIInt size; 10028 PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs; 10029 Mat_Redundant *redund=NULL; 10030 PetscSubcomm psubcomm=NULL; 10031 MPI_Comm subcomm_in=subcomm; 10032 Mat *matseq; 10033 IS isrow,iscol; 10034 PetscBool newsubcomm=PETSC_FALSE; 10035 10036 PetscFunctionBegin; 10037 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10038 if (nsubcomm && reuse == MAT_REUSE_MATRIX) { 10039 PetscValidPointer(*matredundant,5); 10040 PetscValidHeaderSpecific(*matredundant,MAT_CLASSID,5); 10041 } 10042 10043 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10044 if (size == 1 || nsubcomm == 1) { 10045 if (reuse == MAT_INITIAL_MATRIX) { 10046 ierr = MatDuplicate(mat,MAT_COPY_VALUES,matredundant);CHKERRQ(ierr); 10047 } else { 10048 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"); 10049 ierr = MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 10050 } 10051 PetscFunctionReturn(0); 10052 } 10053 10054 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10055 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10056 MatCheckPreallocated(mat,1); 10057 10058 ierr = PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10059 if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */ 10060 /* create psubcomm, then get subcomm */ 10061 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10062 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10063 if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size); 10064 10065 ierr = PetscSubcommCreate(comm,&psubcomm);CHKERRQ(ierr); 10066 ierr = PetscSubcommSetNumber(psubcomm,nsubcomm);CHKERRQ(ierr); 10067 ierr = PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); 10068 ierr = PetscSubcommSetFromOptions(psubcomm);CHKERRQ(ierr); 10069 ierr = PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);CHKERRQ(ierr); 10070 newsubcomm = PETSC_TRUE; 10071 ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 10072 } 10073 10074 /* get isrow, iscol and a local sequential matrix matseq[0] */ 10075 if (reuse == MAT_INITIAL_MATRIX) { 10076 mloc_sub = PETSC_DECIDE; 10077 nloc_sub = PETSC_DECIDE; 10078 if (bs < 1) { 10079 ierr = PetscSplitOwnership(subcomm,&mloc_sub,&M);CHKERRQ(ierr); 10080 ierr = PetscSplitOwnership(subcomm,&nloc_sub,&N);CHKERRQ(ierr); 10081 } else { 10082 ierr = PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);CHKERRQ(ierr); 10083 ierr = PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);CHKERRQ(ierr); 10084 } 10085 ierr = MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);CHKERRQ(ierr); 10086 rstart = rend - mloc_sub; 10087 ierr = ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);CHKERRQ(ierr); 10088 ierr = ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);CHKERRQ(ierr); 10089 } else { /* reuse == MAT_REUSE_MATRIX */ 10090 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"); 10091 /* retrieve subcomm */ 10092 ierr = PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);CHKERRQ(ierr); 10093 redund = (*matredundant)->redundant; 10094 isrow = redund->isrow; 10095 iscol = redund->iscol; 10096 matseq = redund->matseq; 10097 } 10098 ierr = MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);CHKERRQ(ierr); 10099 10100 /* get matredundant over subcomm */ 10101 if (reuse == MAT_INITIAL_MATRIX) { 10102 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);CHKERRQ(ierr); 10103 10104 /* create a supporting struct and attach it to C for reuse */ 10105 ierr = PetscNewLog(*matredundant,&redund);CHKERRQ(ierr); 10106 (*matredundant)->redundant = redund; 10107 redund->isrow = isrow; 10108 redund->iscol = iscol; 10109 redund->matseq = matseq; 10110 if (newsubcomm) { 10111 redund->subcomm = subcomm; 10112 } else { 10113 redund->subcomm = MPI_COMM_NULL; 10114 } 10115 } else { 10116 ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);CHKERRQ(ierr); 10117 } 10118 ierr = PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);CHKERRQ(ierr); 10119 PetscFunctionReturn(0); 10120 } 10121 10122 /*@C 10123 MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from 10124 a given 'mat' object. Each submatrix can span multiple procs. 10125 10126 Collective on Mat 10127 10128 Input Parameters: 10129 + mat - the matrix 10130 . subcomm - the subcommunicator obtained by com_split(comm) 10131 - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10132 10133 Output Parameter: 10134 . subMat - 'parallel submatrices each spans a given subcomm 10135 10136 Notes: 10137 The submatrix partition across processors is dictated by 'subComm' a 10138 communicator obtained by com_split(comm). The comm_split 10139 is not restriced to be grouped with consecutive original ranks. 10140 10141 Due the comm_split() usage, the parallel layout of the submatrices 10142 map directly to the layout of the original matrix [wrt the local 10143 row,col partitioning]. So the original 'DiagonalMat' naturally maps 10144 into the 'DiagonalMat' of the subMat, hence it is used directly from 10145 the subMat. However the offDiagMat looses some columns - and this is 10146 reconstructed with MatSetValues() 10147 10148 Level: advanced 10149 10150 10151 .seealso: MatCreateSubMatrices() 10152 @*/ 10153 PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat) 10154 { 10155 PetscErrorCode ierr; 10156 PetscMPIInt commsize,subCommSize; 10157 10158 PetscFunctionBegin; 10159 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);CHKERRQ(ierr); 10160 ierr = MPI_Comm_size(subComm,&subCommSize);CHKERRQ(ierr); 10161 if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize); 10162 10163 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"); 10164 ierr = PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10165 ierr = (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);CHKERRQ(ierr); 10166 ierr = PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);CHKERRQ(ierr); 10167 PetscFunctionReturn(0); 10168 } 10169 10170 /*@ 10171 MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering 10172 10173 Not Collective 10174 10175 Input Arguments: 10176 mat - matrix to extract local submatrix from 10177 isrow - local row indices for submatrix 10178 iscol - local column indices for submatrix 10179 10180 Output Arguments: 10181 submat - the submatrix 10182 10183 Level: intermediate 10184 10185 Notes: 10186 The submat should be returned with MatRestoreLocalSubMatrix(). 10187 10188 Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be 10189 the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's. 10190 10191 The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then 10192 MatSetValuesBlockedLocal() will also be implemented. 10193 10194 The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that 10195 matrices obtained with DMCreateMatrix() generally already have the local to global mapping provided. 10196 10197 .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping() 10198 @*/ 10199 PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat) 10200 { 10201 PetscErrorCode ierr; 10202 10203 PetscFunctionBegin; 10204 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10205 PetscValidHeaderSpecific(isrow,IS_CLASSID,2); 10206 PetscValidHeaderSpecific(iscol,IS_CLASSID,3); 10207 PetscCheckSameComm(isrow,2,iscol,3); 10208 PetscValidPointer(submat,4); 10209 if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call"); 10210 10211 if (mat->ops->getlocalsubmatrix) { 10212 ierr = (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10213 } else { 10214 ierr = MatCreateLocalRef(mat,isrow,iscol,submat);CHKERRQ(ierr); 10215 } 10216 PetscFunctionReturn(0); 10217 } 10218 10219 /*@ 10220 MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering 10221 10222 Not Collective 10223 10224 Input Arguments: 10225 mat - matrix to extract local submatrix from 10226 isrow - local row indices for submatrix 10227 iscol - local column indices for submatrix 10228 submat - the submatrix 10229 10230 Level: intermediate 10231 10232 .seealso: MatGetLocalSubMatrix() 10233 @*/ 10234 PetscErrorCode MatRestoreLocalSubMatrix(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 (*submat) { 10245 PetscValidHeaderSpecific(*submat,MAT_CLASSID,4); 10246 } 10247 10248 if (mat->ops->restorelocalsubmatrix) { 10249 ierr = (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);CHKERRQ(ierr); 10250 } else { 10251 ierr = MatDestroy(submat);CHKERRQ(ierr); 10252 } 10253 *submat = NULL; 10254 PetscFunctionReturn(0); 10255 } 10256 10257 /* --------------------------------------------------------*/ 10258 /*@ 10259 MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix 10260 10261 Collective on Mat 10262 10263 Input Parameter: 10264 . mat - the matrix 10265 10266 Output Parameter: 10267 . is - if any rows have zero diagonals this contains the list of them 10268 10269 Level: developer 10270 10271 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10272 @*/ 10273 PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is) 10274 { 10275 PetscErrorCode ierr; 10276 10277 PetscFunctionBegin; 10278 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10279 PetscValidType(mat,1); 10280 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10281 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10282 10283 if (!mat->ops->findzerodiagonals) { 10284 Vec diag; 10285 const PetscScalar *a; 10286 PetscInt *rows; 10287 PetscInt rStart, rEnd, r, nrow = 0; 10288 10289 ierr = MatCreateVecs(mat, &diag, NULL);CHKERRQ(ierr); 10290 ierr = MatGetDiagonal(mat, diag);CHKERRQ(ierr); 10291 ierr = MatGetOwnershipRange(mat, &rStart, &rEnd);CHKERRQ(ierr); 10292 ierr = VecGetArrayRead(diag, &a);CHKERRQ(ierr); 10293 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow; 10294 ierr = PetscMalloc1(nrow, &rows);CHKERRQ(ierr); 10295 nrow = 0; 10296 for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart; 10297 ierr = VecRestoreArrayRead(diag, &a);CHKERRQ(ierr); 10298 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10299 ierr = ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);CHKERRQ(ierr); 10300 } else { 10301 ierr = (*mat->ops->findzerodiagonals)(mat, is);CHKERRQ(ierr); 10302 } 10303 PetscFunctionReturn(0); 10304 } 10305 10306 /*@ 10307 MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size) 10308 10309 Collective on Mat 10310 10311 Input Parameter: 10312 . mat - the matrix 10313 10314 Output Parameter: 10315 . is - contains the list of rows with off block diagonal entries 10316 10317 Level: developer 10318 10319 .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd() 10320 @*/ 10321 PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is) 10322 { 10323 PetscErrorCode ierr; 10324 10325 PetscFunctionBegin; 10326 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10327 PetscValidType(mat,1); 10328 if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10329 if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10330 10331 if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined"); 10332 ierr = (*mat->ops->findoffblockdiagonalentries)(mat,is);CHKERRQ(ierr); 10333 PetscFunctionReturn(0); 10334 } 10335 10336 /*@C 10337 MatInvertBlockDiagonal - Inverts the block diagonal entries. 10338 10339 Collective on Mat 10340 10341 Input Parameters: 10342 . mat - the matrix 10343 10344 Output Parameters: 10345 . values - the block inverses in column major order (FORTRAN-like) 10346 10347 Note: 10348 This routine is not available from Fortran. 10349 10350 Level: advanced 10351 10352 .seealso: MatInvertBockDiagonalMat 10353 @*/ 10354 PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values) 10355 { 10356 PetscErrorCode ierr; 10357 10358 PetscFunctionBegin; 10359 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10360 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10361 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10362 if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10363 ierr = (*mat->ops->invertblockdiagonal)(mat,values);CHKERRQ(ierr); 10364 PetscFunctionReturn(0); 10365 } 10366 10367 /*@C 10368 MatInvertVariableBlockDiagonal - Inverts the block diagonal entries. 10369 10370 Collective on Mat 10371 10372 Input Parameters: 10373 + mat - the matrix 10374 . nblocks - the number of blocks 10375 - bsizes - the size of each block 10376 10377 Output Parameters: 10378 . values - the block inverses in column major order (FORTRAN-like) 10379 10380 Note: 10381 This routine is not available from Fortran. 10382 10383 Level: advanced 10384 10385 .seealso: MatInvertBockDiagonal() 10386 @*/ 10387 PetscErrorCode MatInvertVariableBlockDiagonal(Mat mat,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *values) 10388 { 10389 PetscErrorCode ierr; 10390 10391 PetscFunctionBegin; 10392 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10393 if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 10394 if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 10395 if (!mat->ops->invertvariableblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported"); 10396 ierr = (*mat->ops->invertvariableblockdiagonal)(mat,nblocks,bsizes,values);CHKERRQ(ierr); 10397 PetscFunctionReturn(0); 10398 } 10399 10400 /*@ 10401 MatInvertBlockDiagonalMat - set matrix C to be the inverted block diagonal of matrix A 10402 10403 Collective on Mat 10404 10405 Input Parameters: 10406 . A - the matrix 10407 10408 Output Parameters: 10409 . C - matrix with inverted block diagonal of A. This matrix should be created and may have its type set. 10410 10411 Notes: the blocksize of the matrix is used to determine the blocks on the diagonal of C 10412 10413 Level: advanced 10414 10415 .seealso: MatInvertBockDiagonal() 10416 @*/ 10417 PetscErrorCode MatInvertBlockDiagonalMat(Mat A,Mat C) 10418 { 10419 PetscErrorCode ierr; 10420 const PetscScalar *vals; 10421 PetscInt *dnnz; 10422 PetscInt M,N,m,n,rstart,rend,bs,i,j; 10423 10424 PetscFunctionBegin; 10425 ierr = MatInvertBlockDiagonal(A,&vals);CHKERRQ(ierr); 10426 ierr = MatGetBlockSize(A,&bs);CHKERRQ(ierr); 10427 ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr); 10428 ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr); 10429 ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr); 10430 ierr = MatSetBlockSize(C,bs);CHKERRQ(ierr); 10431 ierr = PetscMalloc1(m/bs,&dnnz);CHKERRQ(ierr); 10432 for (j = 0; j < m/bs; j++) dnnz[j] = 1; 10433 ierr = MatXAIJSetPreallocation(C,bs,dnnz,NULL,NULL,NULL);CHKERRQ(ierr); 10434 ierr = PetscFree(dnnz);CHKERRQ(ierr); 10435 ierr = MatGetOwnershipRange(C,&rstart,&rend);CHKERRQ(ierr); 10436 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 10437 for (i = rstart/bs; i < rend/bs; i++) { 10438 ierr = MatSetValuesBlocked(C,1,&i,1,&i,&vals[(i-rstart/bs)*bs*bs],INSERT_VALUES);CHKERRQ(ierr); 10439 } 10440 ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10441 ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 10442 ierr = MatSetOption(C,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 10443 PetscFunctionReturn(0); 10444 } 10445 10446 /*@C 10447 MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created 10448 via MatTransposeColoringCreate(). 10449 10450 Collective on MatTransposeColoring 10451 10452 Input Parameter: 10453 . c - coloring context 10454 10455 Level: intermediate 10456 10457 .seealso: MatTransposeColoringCreate() 10458 @*/ 10459 PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c) 10460 { 10461 PetscErrorCode ierr; 10462 MatTransposeColoring matcolor=*c; 10463 10464 PetscFunctionBegin; 10465 if (!matcolor) PetscFunctionReturn(0); 10466 if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; PetscFunctionReturn(0);} 10467 10468 ierr = PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);CHKERRQ(ierr); 10469 ierr = PetscFree(matcolor->rows);CHKERRQ(ierr); 10470 ierr = PetscFree(matcolor->den2sp);CHKERRQ(ierr); 10471 ierr = PetscFree(matcolor->colorforcol);CHKERRQ(ierr); 10472 ierr = PetscFree(matcolor->columns);CHKERRQ(ierr); 10473 if (matcolor->brows>0) { 10474 ierr = PetscFree(matcolor->lstart);CHKERRQ(ierr); 10475 } 10476 ierr = PetscHeaderDestroy(c);CHKERRQ(ierr); 10477 PetscFunctionReturn(0); 10478 } 10479 10480 /*@C 10481 MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which 10482 a MatTransposeColoring context has been created, computes a dense B^T by Apply 10483 MatTransposeColoring to sparse B. 10484 10485 Collective on MatTransposeColoring 10486 10487 Input Parameters: 10488 + B - sparse matrix B 10489 . Btdense - symbolic dense matrix B^T 10490 - coloring - coloring context created with MatTransposeColoringCreate() 10491 10492 Output Parameter: 10493 . Btdense - dense matrix B^T 10494 10495 Level: advanced 10496 10497 Notes: 10498 These are used internally for some implementations of MatRARt() 10499 10500 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp() 10501 10502 @*/ 10503 PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense) 10504 { 10505 PetscErrorCode ierr; 10506 10507 PetscFunctionBegin; 10508 PetscValidHeaderSpecific(B,MAT_CLASSID,1); 10509 PetscValidHeaderSpecific(Btdense,MAT_CLASSID,2); 10510 PetscValidHeaderSpecific(coloring,MAT_TRANSPOSECOLORING_CLASSID,3); 10511 10512 if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name); 10513 ierr = (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);CHKERRQ(ierr); 10514 PetscFunctionReturn(0); 10515 } 10516 10517 /*@C 10518 MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which 10519 a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense 10520 in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix 10521 Csp from Cden. 10522 10523 Collective on MatTransposeColoring 10524 10525 Input Parameters: 10526 + coloring - coloring context created with MatTransposeColoringCreate() 10527 - Cden - matrix product of a sparse matrix and a dense matrix Btdense 10528 10529 Output Parameter: 10530 . Csp - sparse matrix 10531 10532 Level: advanced 10533 10534 Notes: 10535 These are used internally for some implementations of MatRARt() 10536 10537 .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen() 10538 10539 @*/ 10540 PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp) 10541 { 10542 PetscErrorCode ierr; 10543 10544 PetscFunctionBegin; 10545 PetscValidHeaderSpecific(matcoloring,MAT_TRANSPOSECOLORING_CLASSID,1); 10546 PetscValidHeaderSpecific(Cden,MAT_CLASSID,2); 10547 PetscValidHeaderSpecific(Csp,MAT_CLASSID,3); 10548 10549 if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name); 10550 ierr = (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);CHKERRQ(ierr); 10551 PetscFunctionReturn(0); 10552 } 10553 10554 /*@C 10555 MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T. 10556 10557 Collective on Mat 10558 10559 Input Parameters: 10560 + mat - the matrix product C 10561 - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring() 10562 10563 Output Parameter: 10564 . color - the new coloring context 10565 10566 Level: intermediate 10567 10568 .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(), 10569 MatTransColoringApplyDenToSp() 10570 @*/ 10571 PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color) 10572 { 10573 MatTransposeColoring c; 10574 MPI_Comm comm; 10575 PetscErrorCode ierr; 10576 10577 PetscFunctionBegin; 10578 ierr = PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10579 ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 10580 ierr = PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);CHKERRQ(ierr); 10581 10582 c->ctype = iscoloring->ctype; 10583 if (mat->ops->transposecoloringcreate) { 10584 ierr = (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);CHKERRQ(ierr); 10585 } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type"); 10586 10587 *color = c; 10588 ierr = PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);CHKERRQ(ierr); 10589 PetscFunctionReturn(0); 10590 } 10591 10592 /*@ 10593 MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the 10594 matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the 10595 same, otherwise it will be larger 10596 10597 Not Collective 10598 10599 Input Parameter: 10600 . A - the matrix 10601 10602 Output Parameter: 10603 . state - the current state 10604 10605 Notes: 10606 You can only compare states from two different calls to the SAME matrix, you cannot compare calls between 10607 different matrices 10608 10609 Level: intermediate 10610 10611 @*/ 10612 PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state) 10613 { 10614 PetscFunctionBegin; 10615 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10616 *state = mat->nonzerostate; 10617 PetscFunctionReturn(0); 10618 } 10619 10620 /*@ 10621 MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential 10622 matrices from each processor 10623 10624 Collective 10625 10626 Input Parameters: 10627 + comm - the communicators the parallel matrix will live on 10628 . seqmat - the input sequential matrices 10629 . n - number of local columns (or PETSC_DECIDE) 10630 - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10631 10632 Output Parameter: 10633 . mpimat - the parallel matrix generated 10634 10635 Level: advanced 10636 10637 Notes: 10638 The number of columns of the matrix in EACH processor MUST be the same. 10639 10640 @*/ 10641 PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat) 10642 { 10643 PetscErrorCode ierr; 10644 10645 PetscFunctionBegin; 10646 if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name); 10647 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"); 10648 10649 ierr = PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10650 ierr = (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);CHKERRQ(ierr); 10651 ierr = PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);CHKERRQ(ierr); 10652 PetscFunctionReturn(0); 10653 } 10654 10655 /*@ 10656 MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent 10657 ranks' ownership ranges. 10658 10659 Collective on A 10660 10661 Input Parameters: 10662 + A - the matrix to create subdomains from 10663 - N - requested number of subdomains 10664 10665 10666 Output Parameters: 10667 + n - number of subdomains resulting on this rank 10668 - iss - IS list with indices of subdomains on this rank 10669 10670 Level: advanced 10671 10672 Notes: 10673 number of subdomains must be smaller than the communicator size 10674 @*/ 10675 PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[]) 10676 { 10677 MPI_Comm comm,subcomm; 10678 PetscMPIInt size,rank,color; 10679 PetscInt rstart,rend,k; 10680 PetscErrorCode ierr; 10681 10682 PetscFunctionBegin; 10683 ierr = PetscObjectGetComm((PetscObject)A,&comm);CHKERRQ(ierr); 10684 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 10685 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 10686 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); 10687 *n = 1; 10688 k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */ 10689 color = rank/k; 10690 ierr = MPI_Comm_split(comm,color,rank,&subcomm);CHKERRQ(ierr); 10691 ierr = PetscMalloc1(1,iss);CHKERRQ(ierr); 10692 ierr = MatGetOwnershipRange(A,&rstart,&rend);CHKERRQ(ierr); 10693 ierr = ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);CHKERRQ(ierr); 10694 ierr = MPI_Comm_free(&subcomm);CHKERRQ(ierr); 10695 PetscFunctionReturn(0); 10696 } 10697 10698 /*@ 10699 MatGalerkin - Constructs the coarse grid problem via Galerkin projection. 10700 10701 If the interpolation and restriction operators are the same, uses MatPtAP. 10702 If they are not the same, use MatMatMatMult. 10703 10704 Once the coarse grid problem is constructed, correct for interpolation operators 10705 that are not of full rank, which can legitimately happen in the case of non-nested 10706 geometric multigrid. 10707 10708 Input Parameters: 10709 + restrct - restriction operator 10710 . dA - fine grid matrix 10711 . interpolate - interpolation operator 10712 . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 10713 - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate 10714 10715 Output Parameters: 10716 . A - the Galerkin coarse matrix 10717 10718 Options Database Key: 10719 . -pc_mg_galerkin <both,pmat,mat,none> 10720 10721 Level: developer 10722 10723 .seealso: MatPtAP(), MatMatMatMult() 10724 @*/ 10725 PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A) 10726 { 10727 PetscErrorCode ierr; 10728 IS zerorows; 10729 Vec diag; 10730 10731 PetscFunctionBegin; 10732 if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported"); 10733 /* Construct the coarse grid matrix */ 10734 if (interpolate == restrct) { 10735 ierr = MatPtAP(dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10736 } else { 10737 ierr = MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);CHKERRQ(ierr); 10738 } 10739 10740 /* If the interpolation matrix is not of full rank, A will have zero rows. 10741 This can legitimately happen in the case of non-nested geometric multigrid. 10742 In that event, we set the rows of the matrix to the rows of the identity, 10743 ignoring the equations (as the RHS will also be zero). */ 10744 10745 ierr = MatFindZeroRows(*A, &zerorows);CHKERRQ(ierr); 10746 10747 if (zerorows != NULL) { /* if there are any zero rows */ 10748 ierr = MatCreateVecs(*A, &diag, NULL);CHKERRQ(ierr); 10749 ierr = MatGetDiagonal(*A, diag);CHKERRQ(ierr); 10750 ierr = VecISSet(diag, zerorows, 1.0);CHKERRQ(ierr); 10751 ierr = MatDiagonalSet(*A, diag, INSERT_VALUES);CHKERRQ(ierr); 10752 ierr = VecDestroy(&diag);CHKERRQ(ierr); 10753 ierr = ISDestroy(&zerorows);CHKERRQ(ierr); 10754 } 10755 PetscFunctionReturn(0); 10756 } 10757 10758 /*@C 10759 MatSetOperation - Allows user to set a matrix operation for any matrix type 10760 10761 Logically Collective on Mat 10762 10763 Input Parameters: 10764 + mat - the matrix 10765 . op - the name of the operation 10766 - f - the function that provides the operation 10767 10768 Level: developer 10769 10770 Usage: 10771 $ extern PetscErrorCode usermult(Mat,Vec,Vec); 10772 $ ierr = MatCreateXXX(comm,...&A); 10773 $ ierr = MatSetOperation(A,MATOP_MULT,(void(*)(void))usermult); 10774 10775 Notes: 10776 See the file include/petscmat.h for a complete list of matrix 10777 operations, which all have the form MATOP_<OPERATION>, where 10778 <OPERATION> is the name (in all capital letters) of the 10779 user interface routine (e.g., MatMult() -> MATOP_MULT). 10780 10781 All user-provided functions (except for MATOP_DESTROY) should have the same calling 10782 sequence as the usual matrix interface routines, since they 10783 are intended to be accessed via the usual matrix interface 10784 routines, e.g., 10785 $ MatMult(Mat,Vec,Vec) -> usermult(Mat,Vec,Vec) 10786 10787 In particular each function MUST return an error code of 0 on success and 10788 nonzero on failure. 10789 10790 This routine is distinct from MatShellSetOperation() in that it can be called on any matrix type. 10791 10792 .seealso: MatGetOperation(), MatCreateShell(), MatShellSetContext(), MatShellSetOperation() 10793 @*/ 10794 PetscErrorCode MatSetOperation(Mat mat,MatOperation op,void (*f)(void)) 10795 { 10796 PetscFunctionBegin; 10797 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10798 if (op == MATOP_VIEW && !mat->ops->viewnative && f != (void (*)(void))(mat->ops->view)) { 10799 mat->ops->viewnative = mat->ops->view; 10800 } 10801 (((void(**)(void))mat->ops)[op]) = f; 10802 PetscFunctionReturn(0); 10803 } 10804 10805 /*@C 10806 MatGetOperation - Gets a matrix operation for any matrix type. 10807 10808 Not Collective 10809 10810 Input Parameters: 10811 + mat - the matrix 10812 - op - the name of the operation 10813 10814 Output Parameter: 10815 . f - the function that provides the operation 10816 10817 Level: developer 10818 10819 Usage: 10820 $ PetscErrorCode (*usermult)(Mat,Vec,Vec); 10821 $ ierr = MatGetOperation(A,MATOP_MULT,(void(**)(void))&usermult); 10822 10823 Notes: 10824 See the file include/petscmat.h for a complete list of matrix 10825 operations, which all have the form MATOP_<OPERATION>, where 10826 <OPERATION> is the name (in all capital letters) of the 10827 user interface routine (e.g., MatMult() -> MATOP_MULT). 10828 10829 This routine is distinct from MatShellGetOperation() in that it can be called on any matrix type. 10830 10831 .seealso: MatSetOperation(), MatCreateShell(), MatShellGetContext(), MatShellGetOperation() 10832 @*/ 10833 PetscErrorCode MatGetOperation(Mat mat,MatOperation op,void(**f)(void)) 10834 { 10835 PetscFunctionBegin; 10836 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10837 *f = (((void (**)(void))mat->ops)[op]); 10838 PetscFunctionReturn(0); 10839 } 10840 10841 /*@ 10842 MatHasOperation - Determines whether the given matrix supports the particular 10843 operation. 10844 10845 Not Collective 10846 10847 Input Parameters: 10848 + mat - the matrix 10849 - op - the operation, for example, MATOP_GET_DIAGONAL 10850 10851 Output Parameter: 10852 . has - either PETSC_TRUE or PETSC_FALSE 10853 10854 Level: advanced 10855 10856 Notes: 10857 See the file include/petscmat.h for a complete list of matrix 10858 operations, which all have the form MATOP_<OPERATION>, where 10859 <OPERATION> is the name (in all capital letters) of the 10860 user-level routine. E.g., MatNorm() -> MATOP_NORM. 10861 10862 .seealso: MatCreateShell() 10863 @*/ 10864 PetscErrorCode MatHasOperation(Mat mat,MatOperation op,PetscBool *has) 10865 { 10866 PetscErrorCode ierr; 10867 10868 PetscFunctionBegin; 10869 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10870 PetscValidType(mat,1); 10871 PetscValidPointer(has,3); 10872 if (mat->ops->hasoperation) { 10873 ierr = (*mat->ops->hasoperation)(mat,op,has);CHKERRQ(ierr); 10874 } else { 10875 if (((void**)mat->ops)[op]) *has = PETSC_TRUE; 10876 else { 10877 *has = PETSC_FALSE; 10878 if (op == MATOP_CREATE_SUBMATRIX) { 10879 PetscMPIInt size; 10880 10881 ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 10882 if (size == 1) { 10883 ierr = MatHasOperation(mat,MATOP_CREATE_SUBMATRICES,has);CHKERRQ(ierr); 10884 } 10885 } 10886 } 10887 } 10888 PetscFunctionReturn(0); 10889 } 10890 10891 /*@ 10892 MatHasCongruentLayouts - Determines whether the rows and columns layouts 10893 of the matrix are congruent 10894 10895 Collective on mat 10896 10897 Input Parameters: 10898 . mat - the matrix 10899 10900 Output Parameter: 10901 . cong - either PETSC_TRUE or PETSC_FALSE 10902 10903 Level: beginner 10904 10905 Notes: 10906 10907 .seealso: MatCreate(), MatSetSizes() 10908 @*/ 10909 PetscErrorCode MatHasCongruentLayouts(Mat mat,PetscBool *cong) 10910 { 10911 PetscErrorCode ierr; 10912 10913 PetscFunctionBegin; 10914 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10915 PetscValidType(mat,1); 10916 PetscValidPointer(cong,2); 10917 if (!mat->rmap || !mat->cmap) { 10918 *cong = mat->rmap == mat->cmap ? PETSC_TRUE : PETSC_FALSE; 10919 PetscFunctionReturn(0); 10920 } 10921 if (mat->congruentlayouts == PETSC_DECIDE) { /* first time we compare rows and cols layouts */ 10922 ierr = PetscLayoutCompare(mat->rmap,mat->cmap,cong);CHKERRQ(ierr); 10923 if (*cong) mat->congruentlayouts = 1; 10924 else mat->congruentlayouts = 0; 10925 } else *cong = mat->congruentlayouts ? PETSC_TRUE : PETSC_FALSE; 10926 PetscFunctionReturn(0); 10927 } 10928 10929 /*@ 10930 MatFreeIntermediateDataStructures - Free intermediate data structures created for reuse, 10931 e.g., matrx product of MatPtAP. 10932 10933 Collective on mat 10934 10935 Input Parameters: 10936 . mat - the matrix 10937 10938 Output Parameter: 10939 . mat - the matrix with intermediate data structures released 10940 10941 Level: advanced 10942 10943 Notes: 10944 10945 .seealso: MatPtAP(), MatMatMult() 10946 @*/ 10947 PetscErrorCode MatFreeIntermediateDataStructures(Mat mat) 10948 { 10949 PetscErrorCode ierr; 10950 10951 PetscFunctionBegin; 10952 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 10953 PetscValidType(mat,1); 10954 if (mat->ops->freeintermediatedatastructures) { 10955 ierr = (*mat->ops->freeintermediatedatastructures)(mat);CHKERRQ(ierr); 10956 } 10957 PetscFunctionReturn(0); 10958 } 10959