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