static PetscErrorCode PCSetFromOptions_Composite(PC pc) { PC_Composite *jac = (PC_Composite*)pc->data; PetscErrorCode ierr; PetscInt nmax = 8,i; PC_CompositeLink next; char *pcs[8]; PetscBool flg; PetscFunctionBegin; ierr = PetscOptionsHead("Composite preconditioner options");CHKERRQ(ierr); ierr = PetscOptionsEnum("-pc_composite_type","Type of composition","PCCompositeSetType",PCCompositeTypes,(PetscEnum)jac->type,(PetscEnum*)&jac->type,&flg);CHKERRQ(ierr); if (flg) { ierr = PCCompositeSetType(pc,jac->type);CHKERRQ(ierr); } ierr = PetscOptionsStringArray("-pc_composite_pcs","List of composite solvers","PCCompositeAddPC",pcs,&nmax,&flg);CHKERRQ(ierr); if (flg) { for (i=0; i<nmax; i++) { ierr = PCCompositeAddPC(pc,pcs[i]);CHKERRQ(ierr); ierr = PetscFree(pcs[i]);CHKERRQ(ierr); /* deallocate string pcs[i], which is allocated in PetscOptionsStringArray() */ } } ierr = PetscOptionsTail();CHKERRQ(ierr); next = jac->head; while (next) { ierr = PCSetFromOptions(next->pc);CHKERRQ(ierr); next = next->next; } PetscFunctionReturn(0); }
int main(int argc, char **argv) { PetscErrorCode ierr; PetscInt n=10000,its,dfid=1; Vec x,b,u; Mat A; KSP ksp; PC pc,pcnoise; PCNoise_Ctx ctx={0,NULL}; PetscReal eta=0.1,norm; PetscScalar(*diagfunc)(PetscInt,PetscInt); ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); /* Process command line options */ ierr = PetscOptionsGetInt(NULL,"-n",&n,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-eta",&eta,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-diagfunc",&dfid,NULL);CHKERRQ(ierr); switch(dfid){ case 1: diagfunc = diagFunc1; break; case 2: diagfunc = diagFunc2; break; case 3: diagfunc = diagFunc3; break; default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Unrecognized diagfunc option"); } /* Create a diagonal matrix with a given distribution of diagonal elements */ ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetFromOptions(A);CHKERRQ(ierr); ierr = MatSetUp(A);CHKERRQ(ierr); ierr = AssembleDiagonalMatrix(A,diagfunc);CHKERRQ(ierr); /* Allocate vectors and manufacture an exact solution and rhs */ ierr = MatCreateVecs(A,&x,NULL);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)x,"Computed Solution");CHKERRQ(ierr); ierr = MatCreateVecs(A,&b,NULL);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)b,"RHS");CHKERRQ(ierr); ierr = MatCreateVecs(A,&u,NULL);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)u,"Reference Solution");CHKERRQ(ierr); ierr = VecSet(u,1.0);CHKERRQ(ierr); ierr = MatMult(A,u,b);CHKERRQ(ierr); /* Create a KSP object */ ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = KSPSetOperators(ksp,A,A);CHKERRQ(ierr); /* Set up a composite preconditioner */ ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCCOMPOSITE);CHKERRQ(ierr); /* default composite with single Identity PC */ ierr = PCCompositeSetType(pc,PC_COMPOSITE_ADDITIVE);CHKERRQ(ierr); ierr = PCCompositeAddPC(pc,PCNONE);CHKERRQ(ierr); if(eta > 0){ ierr = PCCompositeAddPC(pc,PCSHELL);CHKERRQ(ierr); ierr = PCCompositeGetPC(pc,1,&pcnoise);CHKERRQ(ierr); ctx.eta = eta; ierr = PCShellSetContext(pcnoise,&ctx);CHKERRQ(ierr); ierr = PCShellSetApply(pcnoise,PCApply_Noise);CHKERRQ(ierr); ierr = PCShellSetSetUp(pcnoise,PCSetup_Noise);CHKERRQ(ierr); ierr = PCShellSetDestroy(pcnoise,PCDestroy_Noise);CHKERRQ(ierr); ierr = PCShellSetName(pcnoise,"Noise PC");CHKERRQ(ierr); } /* Set KSP from options (this can override the PC just defined) */ ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); /* Solve */ ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr); /* Compute error */ ierr = VecAXPY(x,-1.0,u);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)x,"Error");CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error %g, Iterations %D\n",(double)norm,its);CHKERRQ(ierr); /* Destroy objects and finalize */ ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); PetscFinalize(); return 0; }
void PETSC_STDCALL pccompositesettype_(PC pc,PCCompositeType *type, int *__ierr ){ *__ierr = PCCompositeSetType( (PC)PetscToPointer((pc) ),*type); }