static PetscErrorCode KSPChebyshevEstEigSet_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()? */ 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,"esteig_");CHKERRQ(ierr); ierr = KSPSetSkipPCSetFromOptions(cheb->kspest,PETSC_TRUE);CHKERRQ(ierr); ierr = KSPSetPC(cheb->kspest,ksp->pc);CHKERRQ(ierr); ierr = KSPSetComputeEigenvalues(cheb->kspest,PETSC_TRUE);CHKERRQ(ierr); /* We cannot turn off convergence testing because GMRES will break down if you attempt to keep iterating after a zero norm is obtained */ ierr = KSPSetTolerances(cheb->kspest,1.e-12,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->amatid = 0; cheb->pmatid = 0; cheb->amatstate = -1; cheb->pmatstate = -1; } else { ierr = KSPDestroy(&cheb->kspest);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode KSPComputeShifts_GMRES(KSP ksp) { PetscErrorCode ierr; KSP_AGMRES *agmres = (KSP_AGMRES*)(ksp->data); KSP kspgmres; Mat Amat, Pmat; MatStructure flag; PetscInt max_k = agmres->max_k; PC pc; PetscInt m; PetscScalar *Rshift, *Ishift; PetscFunctionBegin; /* Perform one cycle of classical GMRES (with the Arnoldi process) to get the Hessenberg matrix We assume here that the ksp is AGMRES and that the operators for the linear system have been set in this ksp */ ierr = KSPCreate(PetscObjectComm((PetscObject)ksp), &kspgmres);CHKERRQ(ierr); if (!ksp->pc) { ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr); } ierr = PCGetOperators(ksp->pc, &Amat, &Pmat);CHKERRQ(ierr); ierr = KSPSetOperators(kspgmres, Amat, Pmat);CHKERRQ(ierr); ierr = KSPSetFromOptions(kspgmres);CHKERRQ(ierr); ierr = PetscOptionsHasName(NULL, "-ksp_view", &flg);CHKERRQ(ierr); if (flag) { ierr = PetscOptionsClearValue("-ksp_view");CHKERRQ(ierr); } ierr = KSPSetType(kspgmres, KSPGMRES);CHKERRQ(ierr); ierr = KSPGMRESSetRestart(kspgmres, max_k);CHKERRQ(ierr); ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr); ierr = KSPSetPC(kspgmres, pc);CHKERRQ(ierr); /* Copy common options */ kspgmres->pc_side = ksp->pc_side; /* Setup KSP context */ ierr = KSPSetComputeEigenvalues(kspgmres, PETSC_TRUE);CHKERRQ(ierr); ierr = KSPSetUp(kspgmres);CHKERRQ(ierr); kspgmres->max_it = max_k; /* Restrict the maximum number of iterations to one cycle of GMRES */ kspgmres->rtol = ksp->rtol; ierr = KSPSolve(kspgmres, ksp->vec_rhs, ksp->vec_sol);CHKERRQ(ierr); ksp->guess_zero = PETSC_FALSE; ksp->rnorm = kspgmres->rnorm; ksp->its = kspgmres->its; if (kspgmres->reason == KSP_CONVERGED_RTOL) { ksp->reason = KSP_CONVERGED_RTOL; PetscFunctionReturn(0); } else ksp->reason = KSP_CONVERGED_ITERATING; /* Now, compute the Shifts values */ ierr = PetscMalloc2(max_k,&Rshift,max_k,&Ishift);CHKERRQ(ierr); ierr = KSPComputeEigenvalues(kspgmres, max_k, Rshift, Ishift, &m);CHKERRQ(ierr); if (m < max_k) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_PLIB, "Unable to compute the Shifts for the Newton basis"); else { ierr = KSPAGMRESLejaOrdering(Rshift, Ishift, agmres->Rshift, agmres->Ishift, max_k);CHKERRQ(ierr); agmres->HasShifts = PETSC_TRUE; } /* Restore KSP view options */ if (flg) { ierr = PetscOptionsSetValue("-ksp_view", "");CHKERRQ(ierr); } PetscFunctionReturn(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); }
PetscErrorCode efs_setup(efs *slv, int offset[], int stride[]) { PetscErrorCode ierr; PetscInt xs, ys, zs, xm, ym, zm; PCType pc_type; if (efs_log(slv, EFS_LOG_STATUS)) { ierr = ef_io_print(slv->comm, "Setting up electric field solver");CHKERRQ(ierr); } slv->ts = 0; if (efs_log(slv, EFS_LOG_RESIDUAL)) { ierr = PetscOptionsSetValue("-ksp_monitor_short", NULL);CHKERRQ(ierr); } ierr = DMDASetFieldName(slv->dm, 0,"potential");CHKERRQ(ierr); if (slv->grid.nd == 2) { ierr = DMDAGetCorners(slv->dm, &xs, &ys, 0, &xm, &ym, 0);CHKERRQ(ierr); slv->dmap = ef_dmap_create_2d(xs - offset[0], ys - offset[1], xm, ym, stride); } else if (slv->grid.nd == 3) { ierr = DMDAGetCorners(slv->dm, &xs, &ys, &zs, &xm, &ym, &zm);CHKERRQ(ierr); slv->dmap = ef_dmap_create_3d(xs - offset[0], ys - offset[1], zs - offset[2], xm, ym, zm, stride); } else { SETERRQ1(PETSC_COMM_WORLD, PETSC_ERR_SUP, "Unsupported dimmension: %d", slv->grid.nd); } ierr = ef_callback_create(&slv->callback);CHKERRQ(ierr); ierr = KSPCreate(slv->comm, &slv->ksp);CHKERRQ(ierr); if (efs_log(slv, EFS_LOG_EIGS)) { ierr = KSPSetComputeEigenvalues(slv->ksp, PETSC_TRUE);CHKERRQ(ierr); } ierr = KSPSetDM(slv->ksp, slv->dm);CHKERRQ(ierr); ierr = KSPGetPC(slv->ksp, &slv->pc);CHKERRQ(ierr); ierr = PCSetType(slv->pc, PCMG);CHKERRQ(ierr); if (slv->options.galerkin) { ierr = PCMGSetGalerkin(slv->pc, PETSC_TRUE);CHKERRQ(ierr); } else { ierr = PCMGSetGalerkin(slv->pc, PETSC_FALSE);CHKERRQ(ierr); } ierr = KSPSetComputeOperators(slv->ksp, slv->callback->matrix, slv);CHKERRQ(ierr); ierr = KSPSetComputeRHS(slv->ksp, slv->callback->rhs, slv);CHKERRQ(ierr); ierr = KSPSetComputeInitialGuess(slv->ksp, slv->callback->guess, slv);CHKERRQ(ierr); ierr = KSPSetFromOptions(slv->ksp);CHKERRQ(ierr); ierr = PCGetType(slv->pc, &pc_type);CHKERRQ(ierr); ierr = PCMGGetLevels(slv->pc, &slv->options.levels);CHKERRQ(ierr); if (slv->options.levels < 1) slv->options.levels++; ierr = PCMGGetGalerkin(slv->pc, &slv->options.galerkin);CHKERRQ(ierr); if (strcmp(pc_type, PCGAMG) == 0 || strcmp(pc_type, PCHYPRE) == 0) slv->options.galerkin = 1; if (!slv->options.galerkin) { slv->levels = (ef_level*) malloc(slv->options.levels*sizeof(ef_level)); // setup callback for transforming rhs on coarse levels } else { slv->levels = (ef_level*) malloc(sizeof(ef_level)); } ierr = ef_fd_create(&slv->fd, EF_FD_STANDARD_O2);CHKERRQ(ierr); ierr = ef_operator_create(&slv->op, slv->levels, slv->fd, slv->grid.nd);CHKERRQ(ierr); ierr = ef_boundary_create(&slv->boundary, slv->levels, slv->options.levels, slv->dmap, &slv->state, slv->fd);CHKERRQ(ierr); slv->op->axisymmetric = slv->options.axisymmetric; slv->boundary->axisymmetric = slv->options.axisymmetric; ierr = DMSetMatType(slv->dm, MATAIJ);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slv->dm, &slv->levels[0].eps);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slv->dm, &slv->levels[0].g);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slv->dm, &slv->levels[0].ag);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slv->dm, &slv->levels[0].gcomp);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slv->dm, &slv->levels[0].scale);CHKERRQ(ierr); ierr = DMCreateGlobalVector(slv->dm, &slv->levels[0].nscale);CHKERRQ(ierr); ierr = VecSet(slv->levels[0].g, 0);CHKERRQ(ierr); ierr = VecSet(slv->levels[0].gcomp, 1);CHKERRQ(ierr); ierr = VecSet(slv->levels[0].scale, 1);CHKERRQ(ierr); ierr = VecSet(slv->levels[0].nscale, 1);CHKERRQ(ierr); ierr = DMCoarsenHookAdd(slv->dm, slv->callback->coarsen, slv->callback->restrct, slv);CHKERRQ(ierr); return 0; }