int main(int argc,char **args) { PC pc; PetscErrorCode ierr; PetscInt n = 5; Mat mat; ierr = PetscInitialize(&argc,&args,(char*)0,help); if (ierr) return ierr; ierr = PCCreate(PETSC_COMM_WORLD,&pc); CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE); CHKERRQ(ierr); /* Vector and matrix must be set before calling PCSetUp */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,n,n,3,NULL,&mat); CHKERRQ(ierr); ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = PCSetOperators(pc,mat,mat); CHKERRQ(ierr); ierr = PCSetUp(pc); CHKERRQ(ierr); ierr = MatDestroy(&mat); CHKERRQ(ierr); ierr = PCDestroy(&pc); CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode DMCoarsen_AKKT_GAMG11(DM dm, Mat P0f0c, Mat *P1f1c_out) { PetscErrorCode ierr; DM_AKKT* kkt = (DM_AKKT*)(dm->data); Mat Aff = kkt->Aff; /* fine-level KKT matrix */ Mat A1f0f; /* fine-level dual (constraint) Jacobian */ Mat A1f0c; /* = A1f0f*P0f0c coarsen only primal indices */ Mat B1f1f; /* = A1f0c'*A1f0c */ PC gamg11;/* Use PCGAMG internally to get access to some of its methods to operate on B1f1f = A1f0c*A1f0c', where A1f0c = A1f0f*P0f0c. */ PC_GAMG* pc_gamg11; Mat G1f1f; /* = Graph(B1f1f) */ Mat P1f1c; /* = Prolongator(G1f1f); */ PetscCoarsenData *coarsening; PetscFunctionBegin; /* What is faster: - A0c1f = P0f0c'*A0f1f followed by B1f1f = A0c1f'*A0c1f, or - A1f0c = A1f0f*P0f0c followed by B1f1f = A1f0c*A1f0c'? My bet is on the latter: - fewer transpositions inside MatMatMult and row indices are always local. */ ierr = MatGetSubMatrix(Aff, kkt->isf[1], kkt->isf[0], MAT_INITIAL_MATRIX, &A1f0f); CHKERRQ(ierr); if(kkt->transposeP) { ierr = MatMatTransposeMult(A1f0f,P0f0c,MAT_INITIAL_MATRIX, PETSC_DEFAULT, &A1f0c); CHKERRQ(ierr); } ierr = MatMatMult(A1f0f,P0f0c,MAT_INITIAL_MATRIX, PETSC_DEFAULT, &A1f0c); CHKERRQ(ierr); ierr = MatMatTransposeMult(A1f0c, A1f0c, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &B1f1f); CHKERRQ(ierr); /* We create PCGAMG here since it is only needed for coarsening and we don't want to have to carry the attendant data structures, if we don't need them. */ ierr = PCCreate(((PetscObject)dm)->comm, &gamg11); CHKERRQ(ierr); /* This must be an aggregating GAMG. */ ierr = PCSetType(gamg11, PCGAMG); CHKERRQ(ierr); ierr = PCGAMGSetSquareGraph(gamg11, PETSC_FALSE); CHKERRQ(ierr); /* Observe that we want to "square" A1f0c before passing it (B1f1f) to GAMG. This is not because we are not sure how GAMG will deal with a (potentially) non-square matrix, but rather because if we asked GAMG to square it, it would also smooth the resulting prolongator. At least PC_GAMG_AGG would, and we need an unsmoothed prolongator. */ ierr = PCSetOperators(gamg11, B1f1f, B1f1f, DIFFERENT_NONZERO_PATTERN); CHKERRQ(ierr); /* FIX: Currently there is no way to tell GAMG to coarsen onto a give comm, but it shouldn't be hard to hack that stuff in. */ pc_gamg11 = (PC_GAMG*)(gamg11->data); ierr = pc_gamg11->graph(gamg11, B1f1f, &G1f1f); CHKERRQ(ierr); ierr = pc_gamg11->coarsen(gamg11, &G1f1f, &coarsening); CHKERRQ(ierr); ierr = pc_gamg11->prolongator(gamg11, B1f1f, G1f1f, coarsening, &P1f1c); CHKERRQ(ierr); ierr = MatDestroy(&A1f0f); CHKERRQ(ierr); ierr = MatDestroy(&A1f0c); CHKERRQ(ierr); ierr = MatDestroy(&B1f1f); CHKERRQ(ierr); ierr = MatDestroy(&G1f1f); CHKERRQ(ierr); ierr = PCDestroy(&gamg11); CHKERRQ(ierr); *P1f1c_out = P1f1c; PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat mat; Vec b,u; PC pc; PetscErrorCode ierr; PetscInt n = 5,i,col[3]; PetscScalar value[3]; PetscInitialize(&argc,&args,(char *)0,help); /* Create vectors */ ierr = VecCreateSeq(PETSC_COMM_SELF,n,&b);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,n,&u);CHKERRQ(ierr); /* Create and assemble matrix */ ierr = MatCreateSeqDense(PETSC_COMM_SELF,n,n,PETSC_NULL,&mat);CHKERRQ(ierr); value[0] = -1.0; value[1] = 2.0; value[2] = -1.0; for (i=1; i<n-1; i++) { col[0] = i-1; col[1] = i; col[2] = i+1; ierr = MatSetValues(mat,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } i = n - 1; col[0] = n - 2; col[1] = n - 1; ierr = MatSetValues(mat,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0; col[0] = 0; col[1] = 1; value[0] = 2.0; value[1] = -1.0; ierr = MatSetValues(mat,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Create PC context and set up data structures */ ierr = PCCreate(PETSC_COMM_WORLD,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCSOR);CHKERRQ(ierr); ierr = PCSetFromOptions(pc);CHKERRQ(ierr); ierr = PCSetOperators(pc,mat,mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = PCSetUp(pc);CHKERRQ(ierr); value[0] = 1.0; for (i=0; i<n; i++) { ierr = VecSet(u,0.0);CHKERRQ(ierr); ierr = VecSetValues(u,1,&i,value,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(u);CHKERRQ(ierr); ierr = VecAssemblyEnd(u);CHKERRQ(ierr); ierr = PCApply(pc,u,b);CHKERRQ(ierr); ierr = VecView(b,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } /* Free data structures */ ierr = MatDestroy(&mat);CHKERRQ(ierr); ierr = PCDestroy(&pc);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
static PetscErrorCode KSPDestroy_SpecEst(KSP ksp) { PetscErrorCode ierr; KSP_SpecEst *spec = (KSP_SpecEst*)ksp->data; PetscFunctionBegin; ierr = KSPDestroy(&spec->kspest);CHKERRQ(ierr); ierr = KSPDestroy(&spec->kspcheap);CHKERRQ(ierr); ierr = PCDestroy(&spec->pcnone);CHKERRQ(ierr); ierr = PetscFree(ksp->data);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode PCBDDCDestroyFETIDPPC(PC pc) { FETIDPPC_ctx pc_ctx; PetscErrorCode ierr; PetscFunctionBegin; ierr = PCShellGetContext(pc,(void**)&pc_ctx);CHKERRQ(ierr); ierr = VecDestroy(&pc_ctx->lambda_local);CHKERRQ(ierr); ierr = MatDestroy(&pc_ctx->B_Ddelta);CHKERRQ(ierr); ierr = VecScatterDestroy(&pc_ctx->l2g_lambda);CHKERRQ(ierr); ierr = MatDestroy(&pc_ctx->S_j);CHKERRQ(ierr); ierr = PCDestroy(&pc_ctx->pc);CHKERRQ(ierr); /* decrease PCBDDC reference count */ ierr = PetscFree(pc_ctx);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode KSPDestroy_Chebyshev(KSP ksp) { KSP_Chebyshev *cheb = (KSP_Chebyshev*)ksp->data; PetscErrorCode ierr; PetscFunctionBegin; ierr = KSPDestroy(&cheb->kspest);CHKERRQ(ierr); ierr = PCDestroy(&cheb->pcnone);CHKERRQ(ierr); ierr = PetscRandomDestroy(&cheb->random);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)ksp,"KSPChebyshevSetEigenvalues_C",NULL);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)ksp,"KSPChebyshevSetEstimateEigenvalues_C",NULL);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)ksp,"KSPChebyshevEstEigSetRandom_C",NULL);CHKERRQ(ierr); ierr = PetscObjectComposeFunction((PetscObject)ksp,"KSPChebyshevSetNewMatrix_C",NULL);CHKERRQ(ierr); ierr = KSPDestroyDefault(ksp);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode PCBDDCDestroyFETIDPMat(Mat A) { FETIDPMat_ctx mat_ctx; PetscErrorCode ierr; PetscFunctionBegin; ierr = MatShellGetContext(A,(void**)&mat_ctx);CHKERRQ(ierr); ierr = VecDestroy(&mat_ctx->lambda_local);CHKERRQ(ierr); ierr = VecDestroy(&mat_ctx->temp_solution_D);CHKERRQ(ierr); ierr = VecDestroy(&mat_ctx->temp_solution_B);CHKERRQ(ierr); ierr = MatDestroy(&mat_ctx->B_delta);CHKERRQ(ierr); ierr = MatDestroy(&mat_ctx->B_Ddelta);CHKERRQ(ierr); ierr = VecScatterDestroy(&mat_ctx->l2g_lambda);CHKERRQ(ierr); ierr = PCDestroy(&mat_ctx->pc);CHKERRQ(ierr); /* decrease PCBDDC reference count */ ierr = PetscFree(mat_ctx);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode PCDestroy_Composite(PC pc) { PC_Composite *jac = (PC_Composite*)pc->data; PetscErrorCode ierr; PC_CompositeLink next = jac->head,next_tmp; PetscFunctionBegin; ierr = PCReset_Composite(pc);CHKERRQ(ierr); while (next) { ierr = PCDestroy(&next->pc);CHKERRQ(ierr); next_tmp = next; next = next->next; ierr = PetscFree(next_tmp);CHKERRQ(ierr); } ierr = PetscFree(pc->data);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat C,A; PetscInt i,j; PetscErrorCode ierr; PetscScalar v; PC pc; Vec xtmp; PetscInitialize(&argc,&args,(char*)0,help); ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr); ierr = MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,3,3);CHKERRQ(ierr); ierr = MatSetFromOptions(C);CHKERRQ(ierr); ierr = MatSetUp(C);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_WORLD,3,&xtmp);CHKERRQ(ierr); i = 0; j = 0; v = 4; ierr = MatSetValues(C,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); i = 0; j = 2; v = 1; ierr = MatSetValues(C,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); i = 1; j = 0; v = 1; ierr = MatSetValues(C,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); i = 1; j = 1; v = 4; ierr = MatSetValues(C,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); i = 2; j = 1; v = 1; ierr = MatSetValues(C,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PCCreate(PETSC_COMM_WORLD,&pc);CHKERRQ(ierr); ierr = PCSetFromOptions(pc);CHKERRQ(ierr); ierr = PCSetOperators(pc,C,C,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = PCSetUp(pc);CHKERRQ(ierr); ierr = PCFactorGetMatrix(pc,&A);CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PCDestroy(&pc);CHKERRQ(ierr); ierr = VecDestroy(&xtmp);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
static PetscErrorCode PCBDDCDestroyNullSpaceCorrectionPC(PC pc) { NullSpaceCorrection_ctx pc_ctx; PetscErrorCode ierr; PetscFunctionBegin; ierr = PCShellGetContext(pc,(void**)&pc_ctx);CHKERRQ(ierr); ierr = VecDestroy(&pc_ctx->work_small_1);CHKERRQ(ierr); ierr = VecDestroy(&pc_ctx->work_small_2);CHKERRQ(ierr); ierr = VecDestroy(&pc_ctx->work_full_1);CHKERRQ(ierr); ierr = VecDestroy(&pc_ctx->work_full_2);CHKERRQ(ierr); ierr = MatDestroy(&pc_ctx->basis_mat);CHKERRQ(ierr); ierr = MatDestroy(&pc_ctx->Lbasis_mat);CHKERRQ(ierr); ierr = MatDestroy(&pc_ctx->Kbasis_mat);CHKERRQ(ierr); ierr = PCDestroy(&pc_ctx->local_pc);CHKERRQ(ierr); ierr = PetscFree(pc_ctx);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode TSDestroy_Sundials(TS ts) { TS_Sundials *cvode = (TS_Sundials*)ts->data; PetscErrorCode ierr; PetscFunctionBegin; if (cvode->pmat) {ierr = MatDestroy(cvode->pmat);CHKERRQ(ierr);} if (cvode->pc) {ierr = PCDestroy(cvode->pc);CHKERRQ(ierr);} if (cvode->update) {ierr = VecDestroy(cvode->update);CHKERRQ(ierr);} if (cvode->func) {ierr = VecDestroy(cvode->func);CHKERRQ(ierr);} if (cvode->rhs) {ierr = VecDestroy(cvode->rhs);CHKERRQ(ierr);} if (cvode->w1) {ierr = VecDestroy(cvode->w1);CHKERRQ(ierr);} if (cvode->w2) {ierr = VecDestroy(cvode->w2);CHKERRQ(ierr);} ierr = MPI_Comm_free(&(cvode->comm_sundials));CHKERRQ(ierr); if (cvode->mem) {CVodeFree(&cvode->mem);} ierr = PetscFree(cvode);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **args) { PC pc; PetscErrorCode ierr; PetscInt n = 5; Mat mat; PetscInitialize(&argc,&args,(char *)0,help); ierr = PCCreate(PETSC_COMM_WORLD,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); /* Vector and matrix must be set before calling PCSetUp */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,n,n,3,PETSC_NULL,&mat);CHKERRQ(ierr); ierr = PCSetOperators(pc,mat,mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = PCSetUp(pc);CHKERRQ(ierr); ierr = MatDestroy(&mat);CHKERRQ(ierr); ierr = PCDestroy(&pc); CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
static PetscErrorCode KSPChebyshevSetEstimateEigenvalues_Chebyshev(KSP ksp,PetscReal a,PetscReal b,PetscReal c,PetscReal d) { KSP_Chebyshev *cheb = (KSP_Chebyshev*)ksp->data; PetscErrorCode ierr; PetscFunctionBegin; if (a != 0.0 || b != 0.0 || c != 0.0 || d != 0.0) { if (!cheb->kspest) { /* should this block of code be moved to KSPSetUp_Chebyshev()? */ PetscBool nonzero; ierr = KSPCreate(PetscObjectComm((PetscObject)ksp),&cheb->kspest);CHKERRQ(ierr); ierr = PetscObjectIncrementTabLevel((PetscObject)cheb->kspest,(PetscObject)ksp,1);CHKERRQ(ierr); ierr = KSPSetOptionsPrefix(cheb->kspest,((PetscObject)ksp)->prefix);CHKERRQ(ierr); ierr = KSPAppendOptionsPrefix(cheb->kspest,"est_");CHKERRQ(ierr); ierr = KSPGetPC(cheb->kspest,&cheb->pcnone);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)cheb->pcnone);CHKERRQ(ierr); ierr = PCSetType(cheb->pcnone,PCNONE);CHKERRQ(ierr); ierr = KSPSetPC(cheb->kspest,ksp->pc);CHKERRQ(ierr); ierr = KSPGetInitialGuessNonzero(ksp,&nonzero);CHKERRQ(ierr); ierr = KSPSetInitialGuessNonzero(cheb->kspest,nonzero);CHKERRQ(ierr); ierr = KSPSetComputeEigenvalues(cheb->kspest,PETSC_TRUE);CHKERRQ(ierr); /* Estimate with a fixed number of iterations */ ierr = KSPSetConvergenceTest(cheb->kspest,KSPConvergedSkip,0,0);CHKERRQ(ierr); ierr = KSPSetNormType(cheb->kspest,KSP_NORM_NONE);CHKERRQ(ierr); ierr = KSPSetTolerances(cheb->kspest,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,cheb->eststeps);CHKERRQ(ierr); } if (a >= 0) cheb->tform[0] = a; if (b >= 0) cheb->tform[1] = b; if (c >= 0) cheb->tform[2] = c; if (d >= 0) cheb->tform[3] = d; cheb->estimate_current = PETSC_FALSE; } else { ierr = KSPDestroy(&cheb->kspest);CHKERRQ(ierr); ierr = PCDestroy(&cheb->pcnone);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode ComputeKSPFETIDP(DomainData dd, KSP ksp_bddc, KSP *ksp_fetidp) { PetscErrorCode ierr; KSP temp_ksp; PC pc,D; Mat F; PetscFunctionBeginUser; ierr = KSPGetPC(ksp_bddc,&pc);CHKERRQ(ierr); ierr = PCBDDCCreateFETIDPOperators(pc,&F,&D);CHKERRQ(ierr); ierr = KSPCreate(PetscObjectComm((PetscObject)F),&temp_ksp);CHKERRQ(ierr); ierr = KSPSetOperators(temp_ksp,F,F);CHKERRQ(ierr); ierr = KSPSetType(temp_ksp,KSPCG);CHKERRQ(ierr); ierr = KSPSetPC(temp_ksp,D);CHKERRQ(ierr); ierr = KSPSetComputeSingularValues(temp_ksp,PETSC_TRUE);CHKERRQ(ierr); ierr = KSPSetFromOptions(temp_ksp);CHKERRQ(ierr); ierr = KSPSetUp(temp_ksp);CHKERRQ(ierr); *ksp_fetidp = temp_ksp; ierr = MatDestroy(&F);CHKERRQ(ierr); ierr = PCDestroy(&D);CHKERRQ(ierr); PetscFunctionReturn(0); }
void destroyOuterContext(OuterContext* ctx) { if(ctx->outerSol) { VecDestroy(ctx->outerSol); } if(ctx->outerRhs) { VecDestroy(ctx->outerRhs); } if(ctx->outerKsp) { KSPDestroy(ctx->outerKsp); } if(ctx->outerPC) { PCDestroy(ctx->outerPC); } if(ctx->outerMat) { MatDestroy(ctx->outerMat); } if(ctx->root) { destroyRSDtree(ctx->root); } if(ctx->data) { destroyLocalData(ctx->data); } delete ctx; }
PETSC_EXTERN void PETSC_STDCALL pcdestroy_(PC *pc, int *__ierr ){ *__ierr = PCDestroy(pc); }
PetscErrorCode PCBDDCNullSpaceAssembleCorrection(PC pc, PetscBool isdir, IS local_dofs) { PC_BDDC *pcbddc = (PC_BDDC*)pc->data; PC_IS *pcis = (PC_IS*)pc->data; Mat_IS* matis = (Mat_IS*)pc->pmat->data; KSP local_ksp; PC newpc; NullSpaceCorrection_ctx shell_ctx; Mat local_mat,local_pmat,small_mat,inv_small_mat; Vec work1,work2; const Vec *nullvecs; VecScatter scatter_ctx; IS is_aux; MatFactorInfo matinfo; PetscScalar *basis_mat,*Kbasis_mat,*array,*array_mat; PetscScalar one = 1.0,zero = 0.0, m_one = -1.0; PetscInt basis_dofs,basis_size,nnsp_size,i,k; PetscBool nnsp_has_cnst; PetscErrorCode ierr; PetscFunctionBegin; /* Infer the local solver */ ierr = ISGetSize(local_dofs,&basis_dofs);CHKERRQ(ierr); if (isdir) { /* Dirichlet solver */ local_ksp = pcbddc->ksp_D; } else { /* Neumann solver */ local_ksp = pcbddc->ksp_R; } ierr = KSPGetOperators(local_ksp,&local_mat,&local_pmat);CHKERRQ(ierr); /* Get null space vecs */ ierr = MatNullSpaceGetVecs(pcbddc->NullSpace,&nnsp_has_cnst,&nnsp_size,&nullvecs);CHKERRQ(ierr); basis_size = nnsp_size; if (nnsp_has_cnst) { basis_size++; } if (basis_dofs) { /* Create shell ctx */ ierr = PetscNew(&shell_ctx);CHKERRQ(ierr); /* Create work vectors in shell context */ ierr = VecCreate(PETSC_COMM_SELF,&shell_ctx->work_small_1);CHKERRQ(ierr); ierr = VecSetSizes(shell_ctx->work_small_1,basis_size,basis_size);CHKERRQ(ierr); ierr = VecSetType(shell_ctx->work_small_1,VECSEQ);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_small_1,&shell_ctx->work_small_2);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_SELF,&shell_ctx->work_full_1);CHKERRQ(ierr); ierr = VecSetSizes(shell_ctx->work_full_1,basis_dofs,basis_dofs);CHKERRQ(ierr); ierr = VecSetType(shell_ctx->work_full_1,VECSEQ);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&shell_ctx->work_full_2);CHKERRQ(ierr); /* Allocate workspace */ ierr = MatCreateSeqDense(PETSC_COMM_SELF,basis_dofs,basis_size,NULL,&shell_ctx->basis_mat );CHKERRQ(ierr); ierr = MatCreateSeqDense(PETSC_COMM_SELF,basis_dofs,basis_size,NULL,&shell_ctx->Kbasis_mat);CHKERRQ(ierr); ierr = MatDenseGetArray(shell_ctx->basis_mat,&basis_mat);CHKERRQ(ierr); ierr = MatDenseGetArray(shell_ctx->Kbasis_mat,&Kbasis_mat);CHKERRQ(ierr); /* Restrict local null space on selected dofs (Dirichlet or Neumann) and compute matrices N and K*N */ ierr = VecDuplicate(shell_ctx->work_full_1,&work1);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&work2);CHKERRQ(ierr); ierr = VecScatterCreate(pcis->vec1_N,local_dofs,work1,(IS)0,&scatter_ctx);CHKERRQ(ierr); } for (k=0;k<nnsp_size;k++) { ierr = VecScatterBegin(matis->rctx,nullvecs[k],pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(matis->rctx,nullvecs[k],pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); if (basis_dofs) { ierr = VecPlaceArray(work1,(const PetscScalar*)&basis_mat[k*basis_dofs]);CHKERRQ(ierr); ierr = VecScatterBegin(scatter_ctx,pcis->vec1_N,work1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(scatter_ctx,pcis->vec1_N,work1,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecPlaceArray(work2,(const PetscScalar*)&Kbasis_mat[k*basis_dofs]);CHKERRQ(ierr); ierr = MatMult(local_mat,work1,work2);CHKERRQ(ierr); ierr = VecResetArray(work1);CHKERRQ(ierr); ierr = VecResetArray(work2);CHKERRQ(ierr); } } if (basis_dofs) { if (nnsp_has_cnst) { ierr = VecPlaceArray(work1,(const PetscScalar*)&basis_mat[k*basis_dofs]);CHKERRQ(ierr); ierr = VecSet(work1,one);CHKERRQ(ierr); ierr = VecPlaceArray(work2,(const PetscScalar*)&Kbasis_mat[k*basis_dofs]);CHKERRQ(ierr); ierr = MatMult(local_mat,work1,work2);CHKERRQ(ierr); ierr = VecResetArray(work1);CHKERRQ(ierr); ierr = VecResetArray(work2);CHKERRQ(ierr); } ierr = VecDestroy(&work1);CHKERRQ(ierr); ierr = VecDestroy(&work2);CHKERRQ(ierr); ierr = VecScatterDestroy(&scatter_ctx);CHKERRQ(ierr); ierr = MatDenseRestoreArray(shell_ctx->basis_mat,&basis_mat);CHKERRQ(ierr); ierr = MatDenseRestoreArray(shell_ctx->Kbasis_mat,&Kbasis_mat);CHKERRQ(ierr); /* Assemble another Mat object in shell context */ ierr = MatTransposeMatMult(shell_ctx->basis_mat,shell_ctx->Kbasis_mat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&small_mat);CHKERRQ(ierr); ierr = MatFactorInfoInitialize(&matinfo);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,basis_size,0,1,&is_aux);CHKERRQ(ierr); ierr = MatLUFactor(small_mat,is_aux,is_aux,&matinfo);CHKERRQ(ierr); ierr = ISDestroy(&is_aux);CHKERRQ(ierr); ierr = PetscMalloc1(basis_size*basis_size,&array_mat);CHKERRQ(ierr); for (k=0;k<basis_size;k++) { ierr = VecSet(shell_ctx->work_small_1,zero);CHKERRQ(ierr); ierr = VecSetValue(shell_ctx->work_small_1,k,one,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(shell_ctx->work_small_1);CHKERRQ(ierr); ierr = VecAssemblyEnd(shell_ctx->work_small_1);CHKERRQ(ierr); ierr = MatSolve(small_mat,shell_ctx->work_small_1,shell_ctx->work_small_2);CHKERRQ(ierr); ierr = VecGetArrayRead(shell_ctx->work_small_2,(const PetscScalar**)&array);CHKERRQ(ierr); for (i=0;i<basis_size;i++) { array_mat[i*basis_size+k]=array[i]; } ierr = VecRestoreArrayRead(shell_ctx->work_small_2,(const PetscScalar**)&array);CHKERRQ(ierr); } ierr = MatCreateSeqDense(PETSC_COMM_SELF,basis_size,basis_size,array_mat,&inv_small_mat);CHKERRQ(ierr); ierr = MatMatMult(shell_ctx->basis_mat,inv_small_mat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&shell_ctx->Lbasis_mat);CHKERRQ(ierr); ierr = PetscFree(array_mat);CHKERRQ(ierr); ierr = MatDestroy(&inv_small_mat);CHKERRQ(ierr); ierr = MatDestroy(&small_mat);CHKERRQ(ierr); ierr = MatScale(shell_ctx->Kbasis_mat,m_one);CHKERRQ(ierr); /* Rebuild local PC */ ierr = KSPGetPC(local_ksp,&shell_ctx->local_pc);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)shell_ctx->local_pc);CHKERRQ(ierr); ierr = PCCreate(PETSC_COMM_SELF,&newpc);CHKERRQ(ierr); ierr = PCSetOperators(newpc,local_mat,local_mat);CHKERRQ(ierr); ierr = PCSetType(newpc,PCSHELL);CHKERRQ(ierr); ierr = PCShellSetContext(newpc,shell_ctx);CHKERRQ(ierr); ierr = PCShellSetApply(newpc,PCBDDCApplyNullSpaceCorrectionPC);CHKERRQ(ierr); ierr = PCShellSetDestroy(newpc,PCBDDCDestroyNullSpaceCorrectionPC);CHKERRQ(ierr); ierr = PCSetUp(newpc);CHKERRQ(ierr); ierr = KSPSetPC(local_ksp,newpc);CHKERRQ(ierr); ierr = PCDestroy(&newpc);CHKERRQ(ierr); ierr = KSPSetUp(local_ksp);CHKERRQ(ierr); } /* test */ if (pcbddc->dbg_flag && basis_dofs) { KSP check_ksp; PC check_pc; Mat test_mat; Vec work3; PetscReal test_err,lambda_min,lambda_max; PetscBool setsym,issym=PETSC_FALSE; PetscInt tabs; ierr = PetscViewerASCIIGetTab(pcbddc->dbg_viewer,&tabs);CHKERRQ(ierr); ierr = KSPGetPC(local_ksp,&check_pc);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&work1);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&work2);CHKERRQ(ierr); ierr = VecDuplicate(shell_ctx->work_full_1,&work3);CHKERRQ(ierr); ierr = VecSetRandom(shell_ctx->work_small_1,NULL);CHKERRQ(ierr); ierr = MatMult(shell_ctx->basis_mat,shell_ctx->work_small_1,work1);CHKERRQ(ierr); ierr = VecCopy(work1,work2);CHKERRQ(ierr); ierr = MatMult(local_mat,work1,work3);CHKERRQ(ierr); ierr = PCApply(check_pc,work3,work1);CHKERRQ(ierr); ierr = VecAXPY(work1,m_one,work2);CHKERRQ(ierr); ierr = VecNorm(work1,NORM_INFINITY,&test_err);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d error for nullspace correction for ",PetscGlobalRank);CHKERRQ(ierr); ierr = PetscViewerASCIIUseTabs(pcbddc->dbg_viewer,PETSC_FALSE);CHKERRQ(ierr); if (isdir) { ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Dirichlet ");CHKERRQ(ierr); } else { ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Neumann ");CHKERRQ(ierr); } ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"solver is :%1.14e\n",test_err);CHKERRQ(ierr); ierr = PetscViewerASCIISetTab(pcbddc->dbg_viewer,tabs);CHKERRQ(ierr); ierr = PetscViewerASCIIUseTabs(pcbddc->dbg_viewer,PETSC_TRUE);CHKERRQ(ierr); ierr = MatTransposeMatMult(shell_ctx->Lbasis_mat,shell_ctx->Kbasis_mat,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&test_mat);CHKERRQ(ierr); ierr = MatShift(test_mat,one);CHKERRQ(ierr); ierr = MatNorm(test_mat,NORM_INFINITY,&test_err);CHKERRQ(ierr); ierr = MatDestroy(&test_mat);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d error for nullspace matrices is :%1.14e\n",PetscGlobalRank,test_err);CHKERRQ(ierr); /* Create ksp object suitable for extreme eigenvalues' estimation */ ierr = KSPCreate(PETSC_COMM_SELF,&check_ksp);CHKERRQ(ierr); ierr = KSPSetErrorIfNotConverged(check_ksp,pc->erroriffailure);CHKERRQ(ierr); ierr = KSPSetOperators(check_ksp,local_mat,local_mat);CHKERRQ(ierr); ierr = KSPSetTolerances(check_ksp,1.e-8,1.e-8,PETSC_DEFAULT,basis_dofs);CHKERRQ(ierr); ierr = KSPSetComputeSingularValues(check_ksp,PETSC_TRUE);CHKERRQ(ierr); ierr = MatIsSymmetricKnown(pc->pmat,&setsym,&issym);CHKERRQ(ierr); if (issym) { ierr = KSPSetType(check_ksp,KSPCG);CHKERRQ(ierr); } ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); ierr = VecSetRandom(work1,NULL);CHKERRQ(ierr); ierr = MatMult(local_mat,work1,work2);CHKERRQ(ierr); ierr = KSPSolve(check_ksp,work2,work2);CHKERRQ(ierr); ierr = VecAXPY(work2,m_one,work1);CHKERRQ(ierr); ierr = VecNorm(work2,NORM_INFINITY,&test_err);CHKERRQ(ierr); ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max,&lambda_min);CHKERRQ(ierr); ierr = KSPGetIterationNumber(check_ksp,&k);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d error for adapted KSP %1.14e (it %d, eigs %1.6e %1.6e)\n",PetscGlobalRank,test_err,k,lambda_min,lambda_max);CHKERRQ(ierr); ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); ierr = VecDestroy(&work1);CHKERRQ(ierr); ierr = VecDestroy(&work2);CHKERRQ(ierr); ierr = VecDestroy(&work3);CHKERRQ(ierr); } /* all processes shoud call this, even the void ones */ if (pcbddc->dbg_flag) { ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); } PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat mat; /* matrix */ Vec b,ustar,u; /* vectors (RHS, exact solution, approx solution) */ PC pc; /* PC context */ KSP ksp; /* KSP context */ PetscErrorCode ierr; PetscInt n = 10,i,its,col[3]; PetscScalar value[3]; PCType pcname; KSPType kspname; PetscReal norm,tol=1000.*PETSC_MACHINE_EPSILON; PetscInitialize(&argc,&args,(char*)0,help); /* Create and initialize vectors */ ierr = VecCreateSeq(PETSC_COMM_SELF,n,&b);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,n,&ustar);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,n,&u);CHKERRQ(ierr); ierr = VecSet(ustar,1.0);CHKERRQ(ierr); ierr = VecSet(u,0.0);CHKERRQ(ierr); /* Create and assemble matrix */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,n,n,3,NULL,&mat);CHKERRQ(ierr); value[0] = -1.0; value[1] = 2.0; value[2] = -1.0; for (i=1; i<n-1; i++) { col[0] = i-1; col[1] = i; col[2] = i+1; ierr = MatSetValues(mat,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } i = n - 1; col[0] = n - 2; col[1] = n - 1; ierr = MatSetValues(mat,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0; col[0] = 0; col[1] = 1; value[0] = 2.0; value[1] = -1.0; ierr = MatSetValues(mat,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Compute right-hand-side vector */ ierr = MatMult(mat,ustar,b);CHKERRQ(ierr); /* Create PC context and set up data structures */ ierr = PCCreate(PETSC_COMM_WORLD,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); ierr = PCSetFromOptions(pc);CHKERRQ(ierr); ierr = PCSetOperators(pc,mat,mat);CHKERRQ(ierr); ierr = PCSetUp(pc);CHKERRQ(ierr); /* Create KSP context and set up data structures */ ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = KSPSetType(ksp,KSPRICHARDSON);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = PCSetOperators(pc,mat,mat);CHKERRQ(ierr); ierr = KSPSetPC(ksp,pc);CHKERRQ(ierr); ierr = KSPSetUp(ksp);CHKERRQ(ierr); /* Solve the problem */ ierr = KSPGetType(ksp,&kspname);CHKERRQ(ierr); ierr = PCGetType(pc,&pcname);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"Running %s with %s preconditioning\n",kspname,pcname);CHKERRQ(ierr); ierr = KSPSolve(ksp,b,u);CHKERRQ(ierr); ierr = VecAXPY(u,-1.0,ustar);CHKERRQ(ierr); ierr = VecNorm(u,NORM_2,&norm); ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"2 norm of error %g Number of iterations %D\n",(double)norm,its);CHKERRQ(ierr); } /* Free data structures */ ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&ustar);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&mat);CHKERRQ(ierr); ierr = PCDestroy(&pc);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }