int main(int argc,char **args) { Mat A1,A2,A3,A4,nest; Mat mata[4]; Mat aij; MPI_Comm comm; PetscInt m,n,istart,iend,ii,i,J,j; PetscScalar v; PetscMPIInt size; PetscErrorCode ierr; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; comm = PETSC_COMM_WORLD; ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); /* Assemble the matrix for the five point stencil, YET AGAIN */ ierr = MatCreate(comm,&A1);CHKERRQ(ierr); m=2,n=2; ierr = MatSetSizes(A1,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n);CHKERRQ(ierr); ierr = MatSetFromOptions(A1);CHKERRQ(ierr); ierr = MatSetUp(A1);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A1,&istart,&iend);CHKERRQ(ierr); for (ii=istart; ii<iend; ii++) { v = -1.0; i = ii/n; j = ii - i*n; if (i>0) {J = ii - n; ierr = MatSetValues(A1,1,&ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (i<m-1) {J = ii + n; ierr = MatSetValues(A1,1,&ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (j>0) {J = ii - 1; ierr = MatSetValues(A1,1,&ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (j<n-1) {J = ii + 1; ierr = MatSetValues(A1,1,&ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} v = 4.0; ierr = MatSetValues(A1,1,&ii,1,&ii,&v,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatView(A1,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDuplicate(A1,MAT_COPY_VALUES,&A2);CHKERRQ(ierr); ierr = MatDuplicate(A1,MAT_COPY_VALUES,&A3);CHKERRQ(ierr); ierr = MatDuplicate(A1,MAT_COPY_VALUES,&A4);CHKERRQ(ierr); /*create a nest matrix */ ierr = MatCreate(comm,&nest);CHKERRQ(ierr); ierr = MatSetType(nest,MATNEST);CHKERRQ(ierr); mata[0]=A1,mata[1]=A2,mata[2]=A3,mata[3]=A4; ierr = MatNestSetSubMats(nest,2,NULL,2,NULL,mata);CHKERRQ(ierr); ierr = MatSetUp(nest);CHKERRQ(ierr); ierr = MatConvert(nest,MATAIJ,MAT_INITIAL_MATRIX,&aij);CHKERRQ(ierr); ierr = MatView(aij,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&nest);CHKERRQ(ierr); ierr = MatDestroy(&aij);CHKERRQ(ierr); ierr = MatDestroy(&A1);CHKERRQ(ierr); ierr = MatDestroy(&A2);CHKERRQ(ierr); ierr = MatDestroy(&A3);CHKERRQ(ierr); ierr = MatDestroy(&A4);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
/*@ MatCreateSchurComplementPmat - create a preconditioning matrix for the Schur complement by assembling Sp = A11 - A10 inv(diag(A00)) A01 Collective on Mat Input Parameters: + A00,A01,A10,A11 - the four parts of the original matrix A = [A00 A01; A10 A11] (A01,A10, and A11 are optional, implying zero matrices) . ainvtype - type of approximation for inv(A00) used when forming Sp = A11 - A10 inv(A00) A01 - preuse - MAT_INITIAL_MATRIX for a new Sp, or MAT_REUSE_MATRIX to reuse an existing Sp, or MAT_IGNORE_MATRIX to put nothing in Sp Output Parameter: - Spmat - approximate Schur complement suitable for preconditioning S = A11 - A10 inv(diag(A00)) A01 Note: Since the real Schur complement is usually dense, providing a good approximation to newpmat usually requires application-specific information. The default for assembled matrices is to use the inverse of the diagonal of the (0,0) block A00 in place of A00^{-1}. This rarely produce a scalable algorithm. Optionally, A00 can be lumped before forming inv(diag(A00)). Level: advanced Concepts: matrices^submatrices .seealso: MatCreateSchurComplement(), MatGetSchurComplement(), MatSchurComplementGetPmat(), MatSchurComplementAinvType @*/ PetscErrorCode MatCreateSchurComplementPmat(Mat A00,Mat A01,Mat A10,Mat A11,MatSchurComplementAinvType ainvtype,MatReuse preuse,Mat *Spmat) { PetscErrorCode ierr; PetscInt N00; PetscFunctionBegin; /* Use an appropriate approximate inverse of A00 to form A11 - A10 inv(diag(A00)) A01; a NULL A01, A10 or A11 indicates a zero matrix. */ /* TODO: Perhaps should create an appropriately-sized zero matrix of the same type as A00? */ if ((!A01 || !A10) & !A11) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot assemble Spmat: A01, A10 and A11 are all NULL."); if (preuse == MAT_IGNORE_MATRIX) PetscFunctionReturn(0); /* A zero size A00 or empty A01 or A10 imply S = A11. */ ierr = MatGetSize(A00,&N00,NULL);CHKERRQ(ierr); if (!A01 || !A10 || !N00) { if (preuse == MAT_INITIAL_MATRIX) { ierr = MatDuplicate(A11,MAT_COPY_VALUES,Spmat);CHKERRQ(ierr); } else { /* MAT_REUSE_MATRIX */ /* TODO: when can we pass SAME_NONZERO_PATTERN? */ ierr = MatCopy(A11,*Spmat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); } } else { Mat AdB; Vec diag; ierr = MatCreateVecs(A00,&diag,NULL);CHKERRQ(ierr); if (ainvtype == MAT_SCHUR_COMPLEMENT_AINV_LUMP) { ierr = MatGetRowSum(A00,diag);CHKERRQ(ierr); } else if (ainvtype == MAT_SCHUR_COMPLEMENT_AINV_DIAG) { ierr = MatGetDiagonal(A00,diag);CHKERRQ(ierr); } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown MatSchurComplementAinvType: %D", ainvtype); ierr = VecReciprocal(diag);CHKERRQ(ierr); ierr = MatDuplicate(A01,MAT_COPY_VALUES,&AdB);CHKERRQ(ierr); ierr = MatDiagonalScale(AdB,diag,NULL);CHKERRQ(ierr); ierr = VecDestroy(&diag);CHKERRQ(ierr); /* Cannot really reuse Spmat in MatMatMult() because of MatAYPX() --> MatAXPY() --> MatHeaderReplace() --> MatDestroy_XXX_MatMatMult() */ ierr = MatDestroy(Spmat);CHKERRQ(ierr); ierr = MatMatMult(A10,AdB,MAT_INITIAL_MATRIX,PETSC_DEFAULT,Spmat);CHKERRQ(ierr); if (!A11) { ierr = MatScale(*Spmat,-1.0);CHKERRQ(ierr); } else { /* TODO: when can we pass SAME_NONZERO_PATTERN? */ ierr = MatAYPX(*Spmat,-1,A11,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); } ierr = MatDestroy(&AdB);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/* MatConvert_SeqAIJ_SeqCRL converts a SeqAIJ matrix into a * SeqCRL matrix. This routine is called by the MatCreate_SeqCRL() * routine, but can also be used to convert an assembled SeqAIJ matrix * into a SeqCRL one. */ EXTERN_C_BEGIN #undef __FUNCT__ #define __FUNCT__ "MatConvert_SeqAIJ_SeqCRL" PetscErrorCode PETSCMAT_DLLEXPORT MatConvert_SeqAIJ_SeqCRL(Mat A,const MatType type,MatReuse reuse,Mat *newmat) { PetscErrorCode ierr; Mat B = *newmat; Mat_CRL *crl; PetscFunctionBegin; if (reuse == MAT_INITIAL_MATRIX) { ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); } ierr = PetscNewLog(B,Mat_CRL,&crl);CHKERRQ(ierr); B->spptr = (void *) crl; /* Set function pointers for methods that we inherit from AIJ but override. */ B->ops->duplicate = MatDuplicate_CRL; B->ops->assemblyend = MatAssemblyEnd_SeqCRL; B->ops->destroy = MatDestroy_SeqCRL; B->ops->mult = MatMult_CRL; /* If A has already been assembled, compute the permutation. */ if (A->assembled) { ierr = SeqCRL_create_crl(B);CHKERRQ(ierr); } ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQCRL);CHKERRQ(ierr); *newmat = B; PetscFunctionReturn(0); }
PETSC_EXTERN PetscErrorCode MatConvert_MPISBAIJ_MPISBSTRM(Mat A,MatType type,MatReuse reuse,Mat *newmat) { PetscErrorCode ierr; Mat B = *newmat; Mat_SeqSBSTRM *sbstrm; PetscFunctionBegin; if (reuse == MAT_INITIAL_MATRIX) { ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); } /* printf(" --- in MatConvert_MPISBAIJ_MPISBSTRM -- 1 \n"); */ ierr = PetscNewLog(B, Mat_SeqSBSTRM,&sbstrm);CHKERRQ(ierr); B->spptr = (void*)sbstrm; /* Set function pointers for methods that we inherit from AIJ but override. B->ops->duplicate = MatDuplicate_SBSTRM; B->ops->mult = MatMult_SBSTRM; B->ops->destroy = MatDestroy_MPISBSTRM; */ B->ops->assemblyend = MatAssemblyEnd_MPISBSTRM; /* If A has already been assembled, compute the permutation. */ if (A->assembled) { ierr = MPISBSTRM_create_sbstrm(B);CHKERRQ(ierr); } ierr = PetscObjectChangeTypeName((PetscObject) B, MATMPISBSTRM);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)B,"MatMPISBAIJSetPreallocation_C",MatMPISBAIJSetPreallocation_MPISBSTRM);CHKERRQ(ierr); *newmat = B; PetscFunctionReturn(0); }
/* MatConvert_SeqAIJ_SeqAIJPERM converts a SeqAIJ matrix into a * SeqAIJPERM matrix. This routine is called by the MatCreate_SeqAIJPERM() * routine, but can also be used to convert an assembled SeqAIJ matrix * into a SeqAIJPERM one. */ PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJPERM(Mat A,MatType type,MatReuse reuse,Mat *newmat) { PetscErrorCode ierr; Mat B = *newmat; Mat_SeqAIJPERM *aijperm; PetscFunctionBegin; if (reuse == MAT_INITIAL_MATRIX) { ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); } ierr = PetscNewLog(B,&aijperm);CHKERRQ(ierr); B->spptr = (void*) aijperm; /* Set function pointers for methods that we inherit from AIJ but override. */ B->ops->duplicate = MatDuplicate_SeqAIJPERM; B->ops->assemblyend = MatAssemblyEnd_SeqAIJPERM; B->ops->destroy = MatDestroy_SeqAIJPERM; B->ops->mult = MatMult_SeqAIJPERM; B->ops->multadd = MatMultAdd_SeqAIJPERM; /* If A has already been assembled, compute the permutation. */ if (A->assembled) { ierr = MatSeqAIJPERM_create_perm(B);CHKERRQ(ierr); } ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaijperm_seqaij_C",MatConvert_SeqAIJPERM_SeqAIJ);CHKERRQ(ierr); ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJPERM);CHKERRQ(ierr); *newmat = B; PetscFunctionReturn(0); }
PETSC_INTERN PetscErrorCode MatConvert_SeqAIJPERM_SeqAIJ(Mat A,MatType type,MatReuse reuse,Mat *newmat) { /* This routine is only called to convert a MATAIJPERM to its base PETSc type, */ /* so we will ignore 'MatType type'. */ PetscErrorCode ierr; Mat B = *newmat; Mat_SeqAIJPERM *aijperm=(Mat_SeqAIJPERM*)A->spptr; PetscFunctionBegin; if (reuse == MAT_INITIAL_MATRIX) { ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); } /* Reset the original function pointers. */ B->ops->assemblyend = MatAssemblyEnd_SeqAIJ; B->ops->destroy = MatDestroy_SeqAIJ; B->ops->duplicate = MatDuplicate_SeqAIJ; /* Free everything in the Mat_SeqAIJPERM data structure. * We don't free the Mat_SeqAIJPERM struct itself, as this will * cause problems later when MatDestroy() tries to free it. */ if (aijperm->CleanUpAIJPERM) { ierr = PetscFree(aijperm->xgroup);CHKERRQ(ierr); ierr = PetscFree(aijperm->nzgroup);CHKERRQ(ierr); ierr = PetscFree(aijperm->iperm);CHKERRQ(ierr); } /* Change the type of B to MATSEQAIJ. */ ierr = PetscObjectChangeTypeName((PetscObject)B, MATSEQAIJ);CHKERRQ(ierr); *newmat = B; PetscFunctionReturn(0); }
PETSC_EXTERN PetscErrorCode MatConvert_MPIAIJ_MPIAIJCRL(Mat A,MatType type,MatReuse reuse,Mat *newmat) { PetscErrorCode ierr; Mat B = *newmat; Mat_AIJCRL *aijcrl; PetscFunctionBegin; if (reuse == MAT_INITIAL_MATRIX) { ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); } ierr = PetscNewLog(B,Mat_AIJCRL,&aijcrl);CHKERRQ(ierr); B->spptr = (void*) aijcrl; /* Set function pointers for methods that we inherit from AIJ but override. */ B->ops->duplicate = MatDuplicate_AIJCRL; B->ops->assemblyend = MatAssemblyEnd_MPIAIJCRL; B->ops->destroy = MatDestroy_MPIAIJCRL; B->ops->mult = MatMult_AIJCRL; /* If A has already been assembled, compute the permutation. */ if (A->assembled) { ierr = MatMPIAIJCRL_create_aijcrl(B);CHKERRQ(ierr); } ierr = PetscObjectChangeTypeName((PetscObject)B,MATMPIAIJCRL);CHKERRQ(ierr); *newmat = B; PetscFunctionReturn(0); }
PetscErrorCode SNESMonitorJacUpdateSpectrum(SNES snes,PetscInt it,PetscReal fnorm,void *ctx) { #if defined(PETSC_MISSING_LAPACK_GEEV) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - Lapack routine is unavailable\nNot able to provide eigen values."); #elif defined(PETSC_HAVE_ESSL) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"GEEV - No support for ESSL Lapack Routines"); #else Vec X; Mat J,dJ,dJdense; PetscErrorCode ierr; PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*); PetscInt n,i; PetscBLASInt nb,lwork; PetscReal *eigr,*eigi; MatStructure flg = DIFFERENT_NONZERO_PATTERN; PetscScalar *work; PetscScalar *a; PetscFunctionBegin; if (it == 0) PetscFunctionReturn(0); /* create the difference between the current update and the current jacobian */ ierr = SNESGetSolution(snes,&X);CHKERRQ(ierr); ierr = SNESGetJacobian(snes,&J,NULL,&func,NULL);CHKERRQ(ierr); ierr = MatDuplicate(J,MAT_COPY_VALUES,&dJ);CHKERRQ(ierr); ierr = SNESComputeJacobian(snes,X,&dJ,&dJ,&flg);CHKERRQ(ierr); ierr = MatAXPY(dJ,-1.0,J,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* compute the spectrum directly */ ierr = MatConvert(dJ,MATSEQDENSE,MAT_INITIAL_MATRIX,&dJdense);CHKERRQ(ierr); ierr = MatGetSize(dJ,&n,NULL);CHKERRQ(ierr); ierr = PetscBLASIntCast(n,&nb);CHKERRQ(ierr); lwork = 3*nb; ierr = PetscMalloc(n*sizeof(PetscReal),&eigr);CHKERRQ(ierr); ierr = PetscMalloc(n*sizeof(PetscReal),&eigi);CHKERRQ(ierr); ierr = PetscMalloc(lwork*sizeof(PetscScalar),&work);CHKERRQ(ierr); ierr = MatDenseGetArray(dJdense,&a);CHKERRQ(ierr); #if !defined(PETSC_USE_COMPLEX) { PetscBLASInt lierr; ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); PetscStackCall("LAPACKgeev",LAPACKgeev_("N","N",&nb,a,&nb,eigr,eigi,NULL,&nb,NULL,&nb,work,&lwork,&lierr)); if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"geev() error %d",lierr); ierr = PetscFPTrapPop();CHKERRQ(ierr); } #else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not coded for complex"); #endif PetscPrintf(PetscObjectComm((PetscObject)snes),"Eigenvalues of J_%d - J_%d:\n",it,it-1);CHKERRQ(ierr); for (i=0;i<n;i++) { PetscPrintf(PetscObjectComm((PetscObject)snes),"%5d: %20.5g + %20.5gi\n",i,eigr[i],eigi[i]);CHKERRQ(ierr); } ierr = MatDenseRestoreArray(dJdense,&a);CHKERRQ(ierr); ierr = MatDestroy(&dJ);CHKERRQ(ierr); ierr = MatDestroy(&dJdense);CHKERRQ(ierr); ierr = PetscFree(eigr);CHKERRQ(ierr); ierr = PetscFree(eigi);CHKERRQ(ierr); ierr = PetscFree(work);CHKERRQ(ierr); PetscFunctionReturn(0); #endif }
PETSC_EXTERN PetscErrorCode MatConvert_SeqSBAIJ_SeqSBSTRM(Mat A,MatType type,MatReuse reuse,Mat *newmat) { PetscErrorCode ierr; Mat B = *newmat; Mat_SeqSBSTRM *sbstrm; /* PetscInt bs = A->rmap->bs; */ PetscFunctionBegin; if (reuse == MAT_INITIAL_MATRIX) { ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); } ierr = PetscNewLog(B,&sbstrm);CHKERRQ(ierr); B->spptr = (void*) sbstrm; /* Set function pointers for methods that we inherit from BAIJ but override. */ B->ops->duplicate = MatDuplicate_SeqSBSTRM; B->ops->assemblyend = MatAssemblyEnd_SeqSBSTRM; B->ops->destroy = MatDestroy_SeqSBSTRM; /*B->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_sbstrm; B->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_sbstrm; */ /* If A has already been assembled, compute the permutation. */ if (A->assembled) { ierr = SeqSBSTRM_create_sbstrm(B);CHKERRQ(ierr); } ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQSBSTRM);CHKERRQ(ierr); *newmat = B; PetscFunctionReturn(0); }
/*@ MatSchurComplementComputeExplicitOperator - Compute the Schur complement matrix explicitly Collective on Mat Input Parameter: . M - the matrix obtained with MatCreateSchurComplement() Output Parameter: . S - the Schur complement matrix Note: This can be expensive, so it is mainly for testing Level: advanced .seealso: MatCreateSchurComplement(), MatSchurComplementUpdate() @*/ PetscErrorCode MatSchurComplementComputeExplicitOperator(Mat M, Mat *S) { Mat B, C, D; KSP ksp; PC pc; PetscBool isLU, isILU; PetscReal fill = 2.0; PetscErrorCode ierr; PetscFunctionBegin; ierr = MatSchurComplementGetSubMatrices(M, NULL, NULL, &B, &C, &D);CHKERRQ(ierr); ierr = MatSchurComplementGetKSP(M, &ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject) pc, PCLU, &isLU);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject) pc, PCILU, &isILU);CHKERRQ(ierr); if (isLU || isILU) { Mat fact, Bd, AinvB, AinvBd; PetscReal eps = 1.0e-10; /* This can be sped up for banded LU */ ierr = KSPSetUp(ksp);CHKERRQ(ierr); ierr = PCFactorGetMatrix(pc, &fact);CHKERRQ(ierr); ierr = MatConvert(B, MATDENSE, MAT_INITIAL_MATRIX, &Bd);CHKERRQ(ierr); ierr = MatDuplicate(Bd, MAT_DO_NOT_COPY_VALUES, &AinvBd);CHKERRQ(ierr); ierr = MatMatSolve(fact, Bd, AinvBd);CHKERRQ(ierr); ierr = MatDestroy(&Bd);CHKERRQ(ierr); ierr = MatChop(AinvBd, eps);CHKERRQ(ierr); ierr = MatConvert(AinvBd, MATAIJ, MAT_INITIAL_MATRIX, &AinvB);CHKERRQ(ierr); ierr = MatDestroy(&AinvBd);CHKERRQ(ierr); ierr = MatMatMult(C, AinvB, MAT_INITIAL_MATRIX, fill, S);CHKERRQ(ierr); ierr = MatDestroy(&AinvB);CHKERRQ(ierr); } else { Mat Ainvd, Ainv; ierr = PCComputeExplicitOperator(pc, &Ainvd);CHKERRQ(ierr); ierr = MatConvert(Ainvd, MATAIJ, MAT_INITIAL_MATRIX, &Ainv);CHKERRQ(ierr); ierr = MatDestroy(&Ainvd);CHKERRQ(ierr); #if 0 /* Symmetric version */ ierr = MatPtAP(Ainv, B, MAT_INITIAL_MATRIX, fill, S);CHKERRQ(ierr); #else /* Nonsymmetric version */ ierr = MatMatMatMult(C, Ainv, B, MAT_INITIAL_MATRIX, fill, S);CHKERRQ(ierr); #endif ierr = MatDestroy(&Ainv);CHKERRQ(ierr); } ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr); ierr = MatView(*S, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); if (D) { MatInfo info; ierr = MatGetInfo(D, MAT_GLOBAL_SUM, &info);CHKERRQ(ierr); if (info.nz_used) SETERRQ(PetscObjectComm((PetscObject) M), PETSC_ERR_SUP, "Not yet implemented"); } PetscFunctionReturn(0); }
PetscMatrix<Scalar>* PetscMatrix<Scalar>::duplicate() const { PetscMatrix<Scalar>*ptscmatrix = new PetscMatrix<Scalar>(); MatDuplicate(matrix, MAT_COPY_VALUES, &(ptscmatrix->matrix)); ptscmatrix->size = this->size; ptscmatrix->nnz = nnz; return ptscmatrix; };
static PetscErrorCode DMCreateMatrix_Shell(DM dm,Mat *J) { PetscErrorCode ierr; DM_Shell *shell = (DM_Shell*)dm->data; Mat A; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); PetscValidPointer(J,3); if (!shell->A) { if (shell->Xglobal) { PetscInt m,M; ierr = PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation\n"); CHKERRQ(ierr); ierr = VecGetSize(shell->Xglobal,&M); CHKERRQ(ierr); ierr = VecGetLocalSize(shell->Xglobal,&m); CHKERRQ(ierr); ierr = MatCreate(PetscObjectComm((PetscObject)dm),&shell->A); CHKERRQ(ierr); ierr = MatSetSizes(shell->A,m,m,M,M); CHKERRQ(ierr); ierr = MatSetType(shell->A,dm->mattype); CHKERRQ(ierr); ierr = MatSetUp(shell->A); CHKERRQ(ierr); } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector"); } A = shell->A; /* the check below is tacky and incomplete */ if (dm->mattype) { PetscBool flg,aij,seqaij,mpiaij; ierr = PetscObjectTypeCompare((PetscObject)A,dm->mattype,&flg); CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&seqaij); CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&mpiaij); CHKERRQ(ierr); ierr = PetscStrcmp(dm->mattype,MATAIJ,&aij); CHKERRQ(ierr); if (!flg) { if (!(aij && (seqaij || mpiaij))) SETERRQ2(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_NOTSAMETYPE,"Requested matrix of type %s, but only %s available",dm->mattype,((PetscObject)A)->type_name); } } if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */ ierr = PetscObjectReference((PetscObject)A); CHKERRQ(ierr); ierr = MatZeroEntries(A); CHKERRQ(ierr); *J = A; } else { /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */ ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J); CHKERRQ(ierr); ierr = MatZeroEntries(*J); CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode NEPSolve_Interpol(NEP nep) { PetscErrorCode ierr; NEP_INTERPOL *ctx = (NEP_INTERPOL*)nep->data; Mat *A; /*T=nep->function,Tp=nep->jacobian;*/ PetscScalar *x,*fx,t; PetscReal *cs,a,b,s; PetscInt i,j,k,deg=ctx->deg; PetscFunctionBegin; ierr = PetscMalloc4(deg+1,&A,(deg+1)*(deg+1),&cs,deg+1,&x,(deg+1)*nep->nt,&fx);CHKERRQ(ierr); ierr = RGIntervalGetEndpoints(nep->rg,&a,&b,NULL,NULL);CHKERRQ(ierr); ierr = ChebyshevNodes(deg,a,b,x,cs);CHKERRQ(ierr); for (j=0;j<nep->nt;j++) { for (i=0;i<=deg;i++) { ierr = FNEvaluateFunction(nep->f[j],x[i],&fx[i+j*(deg+1)]);CHKERRQ(ierr); } } /* Polynomial coefficients */ for (k=0;k<=deg;k++) { ierr = MatDuplicate(nep->A[0],MAT_COPY_VALUES,&A[k]);CHKERRQ(ierr); t = 0.0; for (i=0;i<deg+1;i++) t += fx[i]*cs[i*(deg+1)+k]; t *= 2.0/(deg+1); if (k==0) t /= 2.0; ierr = MatScale(A[k],t);CHKERRQ(ierr); for (j=1;j<nep->nt;j++) { t = 0.0; for (i=0;i<deg+1;i++) t += fx[i+j*(deg+1)]*cs[i*(deg+1)+k]; t *= 2.0/(deg+1); if (k==0) t /= 2.0; ierr = MatAXPY(A[k],t,nep->A[j],SUBSET_NONZERO_PATTERN);CHKERRQ(ierr); } } ierr = PEPSetOperators(ctx->pep,deg+1,A);CHKERRQ(ierr); for (k=0;k<=deg;k++) { ierr = MatDestroy(&A[k]);CHKERRQ(ierr); } ierr = PetscFree4(A,cs,x,fx);CHKERRQ(ierr); /* Solve polynomial eigenproblem */ ierr = PEPSolve(ctx->pep);CHKERRQ(ierr); ierr = PEPGetConverged(ctx->pep,&nep->nconv);CHKERRQ(ierr); ierr = PEPGetIterationNumber(ctx->pep,&nep->its);CHKERRQ(ierr); ierr = PEPGetConvergedReason(ctx->pep,(PEPConvergedReason*)&nep->reason);CHKERRQ(ierr); s = 2.0/(b-a); for (i=0;i<nep->nconv;i++) { ierr = PEPGetEigenpair(ctx->pep,i,&nep->eigr[i],&nep->eigi[i],NULL,NULL);CHKERRQ(ierr); nep->eigr[i] /= s; nep->eigr[i] += (a+b)/2.0; nep->eigi[i] /= s; } nep->state = NEP_STATE_EIGENVECTORS; PetscFunctionReturn(0); }
/*@ MatSchurComplementComputeExplicitOperator - Compute the Schur complement matrix explicitly Collective on Mat Input Parameter: . M - the matrix obtained with MatCreateSchurComplement() Output Parameter: . S - the Schur complement matrix Note: This can be expensive, so it is mainly for testing Level: advanced .seealso: MatCreateSchurComplement(), MatSchurComplementUpdate() @*/ PetscErrorCode MatSchurComplementComputeExplicitOperator(Mat M, Mat *S) { Mat B, C, D; KSP ksp; PC pc; PetscBool isLU, isILU; PetscReal fill = 2.0; PetscErrorCode ierr; PetscFunctionBegin; ierr = MatSchurComplementGetSubMatrices(M, NULL, NULL, &B, &C, &D);CHKERRQ(ierr); ierr = MatSchurComplementGetKSP(M, &ksp);CHKERRQ(ierr); ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject) pc, PCLU, &isLU);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject) pc, PCILU, &isILU);CHKERRQ(ierr); if (isLU || isILU) { Mat fact, Bd, AinvB, AinvBd; PetscReal eps = 1.0e-10; /* This can be sped up for banded LU */ ierr = KSPSetUp(ksp);CHKERRQ(ierr); ierr = PCFactorGetMatrix(pc, &fact);CHKERRQ(ierr); ierr = MatConvert(B, MATDENSE, MAT_INITIAL_MATRIX, &Bd);CHKERRQ(ierr); ierr = MatDuplicate(Bd, MAT_DO_NOT_COPY_VALUES, &AinvBd);CHKERRQ(ierr); ierr = MatMatSolve(fact, Bd, AinvBd);CHKERRQ(ierr); ierr = MatDestroy(&Bd);CHKERRQ(ierr); ierr = MatChop(AinvBd, eps);CHKERRQ(ierr); ierr = MatConvert(AinvBd, MATAIJ, MAT_INITIAL_MATRIX, &AinvB);CHKERRQ(ierr); ierr = MatDestroy(&AinvBd);CHKERRQ(ierr); ierr = MatMatMult(C, AinvB, MAT_INITIAL_MATRIX, fill, S);CHKERRQ(ierr); ierr = MatDestroy(&AinvB);CHKERRQ(ierr); } else { Mat Ainvd, Ainv; ierr = PCComputeExplicitOperator(pc, &Ainvd);CHKERRQ(ierr); ierr = MatConvert(Ainvd, MATAIJ, MAT_INITIAL_MATRIX, &Ainv);CHKERRQ(ierr); ierr = MatDestroy(&Ainvd);CHKERRQ(ierr); #if 0 /* Symmetric version */ ierr = MatPtAP(Ainv, B, MAT_INITIAL_MATRIX, fill, S);CHKERRQ(ierr); #else /* Nonsymmetric version */ ierr = MatMatMatMult(C, Ainv, B, MAT_INITIAL_MATRIX, fill, S);CHKERRQ(ierr); #endif ierr = MatDestroy(&Ainv);CHKERRQ(ierr); } if (D) { ierr = MatAXPY(*S, -1.0, D, DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); } ierr = MatScale(*S,-1.0);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C MatCompositeMerge - Given a composite matrix, replaces it with a "regular" matrix by summing all the matrices inside the composite matrix. Collective on MPI_Comm Input Parameters: . mat - the composite matrix Options Database: . -mat_composite_merge (you must call MatAssemblyBegin()/MatAssemblyEnd() to have this checked) Level: advanced Notes: The MatType of the resulting matrix will be the same as the MatType of the FIRST matrix in the composite matrix. .seealso: MatDestroy(), MatMult(), MatCompositeAddMat(), MatCreateComposite(), MATCOMPOSITE @*/ PetscErrorCode MatCompositeMerge(Mat mat) { Mat_Composite *shell = (Mat_Composite*)mat->data; Mat_CompositeLink next = shell->head, prev = shell->tail; PetscErrorCode ierr; Mat tmat,newmat; Vec left,right; PetscScalar scale; PetscFunctionBegin; if (!next) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Must provide at least one matrix with MatCompositeAddMat()"); PetscFunctionBegin; if (shell->type == MAT_COMPOSITE_ADDITIVE) { ierr = MatDuplicate(next->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr); while ((next = next->next)) { ierr = MatAXPY(tmat,1.0,next->mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); } } else { ierr = MatDuplicate(next->mat,MAT_COPY_VALUES,&tmat);CHKERRQ(ierr); while ((prev = prev->prev)) { ierr = MatMatMult(tmat,prev->mat,MAT_INITIAL_MATRIX,PETSC_DECIDE,&newmat);CHKERRQ(ierr); ierr = MatDestroy(&tmat);CHKERRQ(ierr); tmat = newmat; } } scale = shell->scale; if ((left = shell->left)) {ierr = PetscObjectReference((PetscObject)left);CHKERRQ(ierr);} if ((right = shell->right)) {ierr = PetscObjectReference((PetscObject)right);CHKERRQ(ierr);} ierr = MatHeaderReplace(mat,&tmat);CHKERRQ(ierr); ierr = MatDiagonalScale(mat,left,right);CHKERRQ(ierr); ierr = MatScale(mat,scale);CHKERRQ(ierr); ierr = VecDestroy(&left);CHKERRQ(ierr); ierr = VecDestroy(&right);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatDuplicate_Transpose(Mat N, MatDuplicateOption op, Mat* m) { Mat_Transpose *Na = (Mat_Transpose*)N->data; PetscErrorCode ierr; PetscFunctionBegin; if (op == MAT_COPY_VALUES) { ierr = MatTranspose(Na->A,MAT_INITIAL_MATRIX,m);CHKERRQ(ierr); } else if (op == MAT_DO_NOT_COPY_VALUES) { ierr = MatDuplicate(Na->A,MAT_DO_NOT_COPY_VALUES,m);CHKERRQ(ierr); ierr = MatTranspose(*m,MAT_INPLACE_MATRIX,m);CHKERRQ(ierr); } else SETERRQ(PetscObjectComm((PetscObject)N),PETSC_ERR_SUP,"MAT_SHARE_NONZERO_PATTERN not supported for this matrix type"); PetscFunctionReturn(0); }
static PetscErrorCode MatCopy_User(Mat A,Mat B,MatStructure str) { User userA,userB; PetscErrorCode ierr; PetscFunctionBegin; ierr = MatShellGetContext(A,&userA);CHKERRQ(ierr); if (userA) { ierr = PetscNew(&userB);CHKERRQ(ierr); ierr = MatDuplicate(userA->A,MAT_COPY_VALUES,&userB->A);CHKERRQ(ierr); ierr = MatShellSetContext(B, userB);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode TSPrecond_Sundials(realtype tn,N_Vector y,N_Vector fy, booleantype jok,booleantype *jcurPtr, realtype _gamma,void *P_data, N_Vector vtemp1,N_Vector vtemp2,N_Vector vtemp3) { TS ts = (TS) P_data; TS_Sundials *cvode = (TS_Sundials*)ts->data; PC pc = cvode->pc; PetscErrorCode ierr; Mat Jac = ts->B; Vec yy = cvode->w1; PetscScalar one = 1.0,gm; MatStructure str = DIFFERENT_NONZERO_PATTERN; PetscScalar *y_data; PetscFunctionBegin; /* This allows us to construct preconditioners in-place if we like */ ierr = MatSetUnfactored(Jac);CHKERRQ(ierr); /* jok - TRUE means reuse current Jacobian else recompute Jacobian */ if (jok) { ierr = MatCopy(cvode->pmat,Jac,str);CHKERRQ(ierr); *jcurPtr = FALSE; } else { /* make PETSc vector yy point to SUNDIALS vector y */ y_data = (PetscScalar *) N_VGetArrayPointer(y); ierr = VecPlaceArray(yy,y_data); CHKERRQ(ierr); /* compute the Jacobian */ ierr = TSComputeRHSJacobian(ts,ts->ptime,yy,&Jac,&Jac,&str);CHKERRQ(ierr); ierr = VecResetArray(yy); CHKERRQ(ierr); /* copy the Jacobian matrix */ if (!cvode->pmat) { ierr = MatDuplicate(Jac,MAT_COPY_VALUES,&cvode->pmat);CHKERRQ(ierr); ierr = PetscLogObjectParent(ts,cvode->pmat);CHKERRQ(ierr); } else { ierr = MatCopy(Jac,cvode->pmat,str);CHKERRQ(ierr); } *jcurPtr = TRUE; } /* construct I-gamma*Jac */ gm = -_gamma; ierr = MatScale(Jac,gm);CHKERRQ(ierr); ierr = MatShift(Jac,one);CHKERRQ(ierr); ierr = PCSetOperators(pc,Jac,Jac,str);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C TaoMatGetSubMat - Gets a submatrix using the IS Input Parameters: + M - the full matrix (n x n) . is - the index set for the submatrix (both row and column index sets need to be the same) . v1 - work vector of dimension n, needed for TAO_SUBSET_MASK option - subset_type - the method TAO is using for subsetting (TAO_SUBSET_SUBVEC, TAO_SUBSET_MASK, TAO_SUBSET_MATRIXFREE) Output Parameters: . Msub - the submatrix @*/ PetscErrorCode TaoMatGetSubMat(Mat M, IS is, Vec v1, TaoSubsetType subset_type, Mat *Msub) { PetscErrorCode ierr; IS iscomp; PetscBool flg = PETSC_FALSE; PetscFunctionBegin; PetscValidHeaderSpecific(M,MAT_CLASSID,1); PetscValidHeaderSpecific(is,IS_CLASSID,2); ierr = MatDestroy(Msub);CHKERRQ(ierr); switch (subset_type) { case TAO_SUBSET_SUBVEC: ierr = MatGetSubMatrix(M, is, is, MAT_INITIAL_MATRIX, Msub);CHKERRQ(ierr); break; case TAO_SUBSET_MASK: /* Get Reduced Hessian Msub[i,j] = M[i,j] if i,j in Free_Local or i==j Msub[i,j] = 0 if i!=j and i or j not in Free_Local */ ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)M),NULL,NULL,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-different_submatrix","use separate hessian matrix when computing submatrices","TaoSubsetType",flg,&flg,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); if (flg) { ierr = MatDuplicate(M, MAT_COPY_VALUES, Msub);CHKERRQ(ierr); } else { /* Act on hessian directly (default) */ ierr = PetscObjectReference((PetscObject)M);CHKERRQ(ierr); *Msub = M; } /* Save the diagonal to temporary vector */ ierr = MatGetDiagonal(*Msub,v1);CHKERRQ(ierr); /* Zero out rows and columns */ ierr = ISComplementVec(is,v1,&iscomp);CHKERRQ(ierr); /* Use v1 instead of 0 here because of PETSc bug */ ierr = MatZeroRowsColumnsIS(*Msub,iscomp,1.0,v1,v1);CHKERRQ(ierr); ierr = ISDestroy(&iscomp);CHKERRQ(ierr); break; case TAO_SUBSET_MATRIXFREE: ierr = ISComplementVec(is,v1,&iscomp);CHKERRQ(ierr); ierr = MatCreateSubMatrixFree(M,iscomp,iscomp,Msub);CHKERRQ(ierr); ierr = ISDestroy(&iscomp);CHKERRQ(ierr); break; } PetscFunctionReturn(0); }
int main(int argc,char **args) { PetscErrorCode ierr; Mat A,B,C; PetscBool different=PETSC_FALSE,skip=PETSC_FALSE; PetscInt m0,m1,n=128,i; PetscInitialize(&argc,&args,(char*)0,help); ierr = PetscOptionsGetBool(NULL,"-different",&different,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,"-skip",&skip,NULL);CHKERRQ(ierr); /* Create matrices A = tridiag(1,-2,1) and B = diag(7); */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&B);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetSizes(B,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetFromOptions(B);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = MatSetUp(B);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A,&m0,&m1);CHKERRQ(ierr); for (i=m0;i<m1;i++) { if (i>0) { ierr = MatSetValue(A,i,i-1,-1.0,INSERT_VALUES);CHKERRQ(ierr); } if (i<n-1) { ierr = MatSetValue(A,i,i+1,-1.0,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatSetValue(A,i,i,2.0,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValue(B,i,i,7.0,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatDuplicate(A,MAT_COPY_VALUES,&C);CHKERRQ(ierr); /* Add B */ ierr = MatAXPY(C,1.0,B,(different)?DIFFERENT_NONZERO_PATTERN:SUBSET_NONZERO_PATTERN);CHKERRQ(ierr); /* Add A */ if (!skip) { ierr = MatAXPY(C,1.0,A,SUBSET_NONZERO_PATTERN);CHKERRQ(ierr); } /* Free memory */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
PetscErrorCode TestMatZeroRows_with_no_allocation(Mat A,IS is,PetscScalar diag) { Mat B; PetscErrorCode ierr; /* Now copy A into B, and test it with MatZeroRows() */ ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); /* Set this flag after assembly. This way, it affects only MatZeroRows() */ ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); ierr = MatZeroRowsIS(B,is,diag,0,0);CHKERRQ(ierr); ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); return 0; }
PETSC_INTERN PetscErrorCode MatConvert_MPIAIJ_MPIAIJMKL(Mat A,MatType type,MatReuse reuse,Mat *newmat) { PetscErrorCode ierr; Mat B = *newmat; PetscFunctionBegin; if (reuse == MAT_INITIAL_MATRIX) { ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); } ierr = PetscObjectChangeTypeName((PetscObject) B, MATMPIAIJMKL);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)B,"MatMPIAIJSetPreallocation_C",MatMPIAIJSetPreallocation_MPIAIJMKL);CHKERRQ(ierr); *newmat = B; PetscFunctionReturn(0); }
void StaggeredStokesPETScLevelSolver::initializeSolverStateSpecialized( const SAMRAIVectorReal<NDIM, double>& x, const SAMRAIVectorReal<NDIM, double>& /*b*/) { // Allocate DOF index data. Pointer<PatchLevel<NDIM> > level = d_hierarchy->getPatchLevel(d_level_num); if (!level->checkAllocated(d_u_dof_index_idx)) level->allocatePatchData(d_u_dof_index_idx); if (!level->checkAllocated(d_p_dof_index_idx)) level->allocatePatchData(d_p_dof_index_idx); // Setup PETSc objects. int ierr; StaggeredStokesPETScVecUtilities::constructPatchLevelDOFIndices( d_num_dofs_per_proc, d_u_dof_index_idx, d_p_dof_index_idx, level); const int mpi_rank = SAMRAI_MPI::getRank(); ierr = VecCreateMPI( PETSC_COMM_WORLD, d_num_dofs_per_proc[mpi_rank], PETSC_DETERMINE, &d_petsc_x); IBTK_CHKERRQ(ierr); ierr = VecCreateMPI( PETSC_COMM_WORLD, d_num_dofs_per_proc[mpi_rank], PETSC_DETERMINE, &d_petsc_b); IBTK_CHKERRQ(ierr); StaggeredStokesPETScMatUtilities::constructPatchLevelMACStokesOp(d_petsc_mat, d_U_problem_coefs, d_U_bc_coefs, d_new_time, d_num_dofs_per_proc, d_u_dof_index_idx, d_p_dof_index_idx, level); ierr = MatDuplicate(d_petsc_mat, MAT_COPY_VALUES, &d_petsc_pc); IBTK_CHKERRQ(ierr); HierarchyDataOpsManager<NDIM>* hier_ops_manager = HierarchyDataOpsManager<NDIM>::getManager(); Pointer<HierarchyDataOpsInteger<NDIM> > hier_p_dof_index_ops = hier_ops_manager->getOperationsInteger(d_p_dof_index_var, d_hierarchy, true); hier_p_dof_index_ops->resetLevels(d_level_num, d_level_num); const int min_p_idx = hier_p_dof_index_ops->min( d_p_dof_index_idx); // NOTE: HierarchyDataOpsInteger::max() is broken ierr = MatZeroRowsColumns(d_petsc_pc, 1, &min_p_idx, 1.0, NULL, NULL); IBTK_CHKERRQ(ierr); d_petsc_ksp_ops_flag = SAME_PRECONDITIONER; const int u_idx = x.getComponentDescriptorIndex(0); const int p_idx = x.getComponentDescriptorIndex(1); d_data_synch_sched = StaggeredStokesPETScVecUtilities::constructDataSynchSchedule(u_idx, p_idx, level); d_ghost_fill_sched = StaggeredStokesPETScVecUtilities::constructGhostFillSchedule(u_idx, p_idx, level); return; } // initializeSolverStateSpecialized
RawGraph(Mat new_global_mat) { global_mat = new_global_mat; //For this code to work, we're going to need the matrix structure for the sequential portion of this matrix. //Therefore, extract a sequential AIJ matrix. MatType type; MatGetType(global_mat, &type); if (!strcmp(type,MATSEQAIJ)) { MatDuplicate(global_mat, MAT_DO_NOT_COPY_VALUES, &local_mat); } else { MatGetLocalMat(global_mat, MAT_INITIAL_MATRIX, &local_mat); } MatZeroEntries(local_mat); MatGetOwnershipRange(global_mat, &row_begin, &row_end); //MatView(local_mat, PETSC_VIEWER_DRAW_SELF); seq_raw.create(local_mat); }
int main(int argc,char **args) { Mat A,Ar,C; PetscViewer fd; /* viewer */ char file[PETSC_MAX_PATH_LEN]; /* input file name */ PetscErrorCode ierr; PetscInt ns=2,np; PetscSubcomm subc; PetscBool flg; PetscInitialize(&argc,&args,(char*)0,help); /* Determine files from which we read the two linear systems (matrix and right-hand-side vector). */ ierr = PetscOptionsGetString(NULL,"-f0",file,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate binary file with the -f0 option"); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&np);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Reading matrix with %d processors\n",np);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatLoad(A,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); /* Determines amount of subcomunicators */ ierr = PetscOptionsGetInt(NULL,"-nsub",&ns,NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Splitting in %d subcommunicators\n",ns);CHKERRQ(ierr); ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)A),&subc);CHKERRQ(ierr); ierr = PetscSubcommSetNumber(subc,ns);CHKERRQ(ierr); ierr = PetscSubcommSetType(subc,PETSC_SUBCOMM_CONTIGUOUS);CHKERRQ(ierr); ierr = PetscSubcommSetFromOptions(subc);CHKERRQ(ierr); ierr = MatCreateRedundantMatrix(A,0,PetscSubcommChild(subc),MAT_INITIAL_MATRIX,&Ar);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Copying matrix\n",ns);CHKERRQ(ierr); ierr = MatDuplicate(Ar,MAT_COPY_VALUES,&C);CHKERRQ(ierr); ierr = PetscSubcommDestroy(&subc);CHKERRQ(ierr); /* Free memory */ ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&Ar);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
PetscErrorCode interpPeriodicMatrix(PetscScalar tc, Mat *A, PetscScalar cyclePeriod, PetscInt numPeriods, PetscScalar *tdp, PeriodicMat *user, char *filename) { /* Function to interpolate a matrix that is periodic in time with period cyclePeriod. */ /* tc is the current time and numPeriods is the number of instances per period */ /* at which data are available (to be read from files). */ /* IMPORTANT: Matrix *A MUST have been created and preallocated before */ /* calling this routine. All other matrices will be created using *A as a template. */ #include <math.h> PetscScalar t,t1; PetscInt im,it0,it1; /* static PetscInt iCurrTimeReadLast=-1; */ PetscErrorCode ierr; PetscScalar alpha[2]; char tmpFile[PETSC_MAX_PATH_LEN]; if (user->firstTime) { if (numPeriods>MAX_MATRIX_PERIODS) { SETERRQ(1,"Number of allowable matrices in PeriodicMat struct exceeded by requested number ! Increase MAX_MATRIX_PERIODS."); } user->numPeriods = numPeriods; for (im=0; im<numPeriods; im++) { ierr = MatDuplicate(*A,MAT_DO_NOT_COPY_VALUES,&user->Ap[im]);CHKERRQ(ierr); strcpy(tmpFile,""); sprintf(tmpFile,"%s%02d",filename,im); ierr = PetscPrintf(PETSC_COMM_WORLD,"Reading matrix from file %s\n", tmpFile);CHKERRQ(ierr); ierr = MatLoadIntoMatrix3(tmpFile,user->Ap[im]); } user->firstTime = PETSC_FALSE; } t=tc; /* current time */ if (t<0.) t=cyclePeriod+t; t1=t-cyclePeriod*floor(t/cyclePeriod); ierr=calcPeriodicInterpFactor(numPeriods,t1,tdp,&it0,&it1,&alpha[0],&alpha[1]); CHKERRQ(ierr); /* ierr = PetscPrintf(PETSC_COMM_WORLD,"tc=%lf,t1=%lf,it0=%d,it1=%d,a1=%17.16lf,a2=%17.16lf\n",tc,t1,it0,it1,alpha[0],alpha[1]);CHKERRQ(ierr); */ /* interpolate to current time */ ierr = MatAXPBYmy(alpha[0],alpha[1],user->Ap[it0],user->Ap[it1],A);CHKERRQ(ierr); return 0; }
PetscErrorCode MatDuplicate_IS(Mat mat,MatDuplicateOption op,Mat *newmat) { PetscErrorCode ierr; Mat_IS *matis = (Mat_IS*)(mat->data); PetscInt bs,m,n,M,N; Mat B,localmat; PetscFunctionBegin; ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr); ierr = MatGetLocalSize(mat,&m,&n);CHKERRQ(ierr); ierr = MatCreateIS(PetscObjectComm((PetscObject)mat),bs,m,n,M,N,matis->mapping,&B);CHKERRQ(ierr); ierr = MatDuplicate(matis->A,op,&localmat);CHKERRQ(ierr); ierr = MatISSetLocalMat(B,localmat);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); *newmat = B; PetscFunctionReturn(0); }
PetscErrorCode TestMatZeroRows_Basic(Mat A,IS is,PetscScalar diag) { Mat B; PetscErrorCode ierr; PetscBool keepnonzeropattern; /* Now copy A into B, and test it with MatZeroRows() */ ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL,NULL,"-keep_nonzero_pattern",&keepnonzeropattern);CHKERRQ(ierr); if (keepnonzeropattern) { ierr = MatSetOption(B,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); } ierr = MatZeroRowsIS(B,is,diag,0,0);CHKERRQ(ierr); ierr = MatView(B,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); return 0; }
PetscErrorCode DMCreateMatrix_AKKT(DM dm, const MatType type, Mat *A) { PetscBool iskkt; PetscErrorCode ierr; DM_AKKT* kkt = (DM_AKKT*)(dm->data); PetscFunctionBegin; PetscValidHeaderSpecific(dm, DM_CLASSID,1); ierr = PetscObjectTypeCompare((PetscObject)dm, DMAKKT, &iskkt); CHKERRQ(ierr); if(!iskkt) SETERRQ(((PetscObject)dm)->comm, PETSC_ERR_ARG_WRONG, "DM not of type DMAKKT"); if(A) { if(kkt->duplicate_mat) { ierr = MatDuplicate(kkt->Aff, MAT_SHARE_NONZERO_PATTERN, A); CHKERRQ(ierr); } else { ierr = PetscObjectReference((PetscObject)(kkt->Aff)); CHKERRQ(ierr); *A = kkt->Aff; } } PetscFunctionReturn(0); }
int main(int argc,char **argv) { SNES snes; /* nonlinear solver context */ Vec r; /* solution, residual vectors */ PetscErrorCode ierr; AppCtx user; /* user-defined work context */ PetscViewer viewer; PetscInitialize(&argc,&argv,(char*)0,help); ierr = PetscViewerBinaryOpen(PETSC_COMM_SELF,"videfinition",FILE_MODE_READ,&viewer);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_SELF,&user.M);CHKERRQ(ierr); ierr = MatLoad(user.M,viewer);CHKERRQ(ierr); ierr = MatDuplicate(user.M,MAT_COPY_VALUES,&user.Jac);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF,&user.q);CHKERRQ(ierr); ierr = VecLoad(user.q,viewer);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF,&user.lb);CHKERRQ(ierr); ierr = VecLoad(user.lb,viewer);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF,&user.ub);CHKERRQ(ierr);ierr = VecLoad(user.ub,viewer);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF,&user.zz);CHKERRQ(ierr);ierr = VecLoad(user.zz,viewer);CHKERRQ(ierr); ierr = VecView(user.zz,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); /* ierr = VecSet(user.zz,0.01);CHKERRQ(ierr);*/ ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); ierr = VecDuplicate(user.q,&r);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create nonlinear solver context - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetFunction(snes,r,FormFunction1,&user);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,user.Jac,user.Jac,FormJacobian1,&user);CHKERRQ(ierr); ierr = SNESVISetVariableBounds(snes,user.lb,user.ub);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,user.zz);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)user.zz,"x*");CHKERRQ(ierr); ierr = VecView(user.zz,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)r,"f(x*)");CHKERRQ(ierr); ierr = FormFunction1(snes,user.zz,r,&user);CHKERRQ(ierr); ierr = VecView(r,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }