PetscErrorCode KSPSetUp_Richardson(KSP ksp) { PetscErrorCode ierr; KSP_Richardson *richardsonP = (KSP_Richardson*)ksp->data; PetscFunctionBegin; if (richardsonP->selfscale) { ierr = KSPSetWorkVecs(ksp,4);CHKERRQ(ierr); } else { ierr = KSPSetWorkVecs(ksp,2);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode KSPSetUp_FCG(KSP ksp) { PetscErrorCode ierr; KSP_FCG *fcg = (KSP_FCG*)ksp->data; PetscInt maxit = ksp->max_it; const PetscInt nworkstd = 2; PetscFunctionBegin; /* Allocate "standard" work vectors (not including the basis and transformed basis vectors) */ ierr = KSPSetWorkVecs(ksp,nworkstd);CHKERRQ(ierr); /* Allocated space for pointers to additional work vectors note that mmax is the number of previous directions, so we add 1 for the current direction, and an extra 1 for the prealloc (which might be empty) */ ierr = PetscMalloc5(fcg->mmax+1,&fcg->Pvecs,fcg->mmax+1,&fcg->Cvecs,fcg->mmax+1,&fcg->pPvecs,fcg->mmax+1,&fcg->pCvecs,fcg->mmax+2,&fcg->chunksizes);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)ksp,2*(fcg->mmax+1)*sizeof(Vec*) + 2*(fcg->mmax + 1)*sizeof(Vec**) + (fcg->mmax + 2)*sizeof(PetscInt));CHKERRQ(ierr); /* Preallocate additional work vectors */ ierr = KSPAllocateVectors_FCG(ksp,fcg->nprealloc,fcg->nprealloc);CHKERRQ(ierr); /* If user requested computations of eigenvalues then allocate work work space needed */ if (ksp->calc_sings) { /* get space to store tridiagonal matrix for Lanczos */ ierr = PetscMalloc4(maxit,&fcg->e,maxit,&fcg->d,maxit,&fcg->ee,maxit,&fcg->dd);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)ksp,2*(maxit+1)*(sizeof(PetscScalar)+sizeof(PetscReal)));CHKERRQ(ierr); ksp->ops->computeextremesingularvalues = KSPComputeExtremeSingularValues_CG; ksp->ops->computeeigenvalues = KSPComputeEigenvalues_CG; } PetscFunctionReturn(0); }
PetscErrorCode KSPSetUp_CG(KSP ksp) { KSP_CG *cgP = (KSP_CG*)ksp->data; PetscErrorCode ierr; PetscInt maxit = ksp->max_it,nwork = 3; PetscFunctionBegin; /* get work vectors needed by CG */ if (cgP->singlereduction) nwork += 2; ierr = KSPSetWorkVecs(ksp,nwork);CHKERRQ(ierr); /* If user requested computations of eigenvalues then allocate work work space needed */ if (ksp->calc_sings) { /* get space to store tridiagonal matrix for Lanczos */ ierr = PetscMalloc4(maxit+1,&cgP->e,maxit+1,&cgP->d,maxit+1,&cgP->ee,maxit+1,&cgP->dd);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)ksp,2*(maxit+1)*(sizeof(PetscScalar)+sizeof(PetscReal)));CHKERRQ(ierr); ksp->ops->computeextremesingularvalues = KSPComputeExtremeSingularValues_CG; ksp->ops->computeeigenvalues = KSPComputeEigenvalues_CG; } PetscFunctionReturn(0); }
static PetscErrorCode KSPSetUp_PIPEFCG(KSP ksp) { PetscErrorCode ierr; KSP_PIPEFCG *pipefcg; const PetscInt nworkstd = 5; PetscFunctionBegin; pipefcg = (KSP_PIPEFCG*)ksp->data; /* Allocate "standard" work vectors (not including the basis and transformed basis vectors) */ ierr = KSPSetWorkVecs(ksp,nworkstd);CHKERRQ(ierr); /* Allocated space for pointers to additional work vectors note that mmax is the number of previous directions, so we add 1 for the current direction, and an extra 1 for the prealloc (which might be empty) */ ierr = PetscMalloc4(pipefcg->mmax+1,&(pipefcg->Pvecs),pipefcg->mmax+1,&(pipefcg->pPvecs),pipefcg->mmax+1,&(pipefcg->Svecs),pipefcg->mmax+1,&(pipefcg->pSvecs));CHKERRQ(ierr); ierr = PetscMalloc4(pipefcg->mmax+1,&(pipefcg->Qvecs),pipefcg->mmax+1,&(pipefcg->pQvecs),pipefcg->mmax+1,&(pipefcg->ZETAvecs),pipefcg->mmax+1,&(pipefcg->pZETAvecs));CHKERRQ(ierr); ierr = PetscMalloc4(pipefcg->mmax+1,&(pipefcg->Pold),pipefcg->mmax+1,&(pipefcg->Sold),pipefcg->mmax+1,&(pipefcg->Qold),pipefcg->mmax+1,&(pipefcg->ZETAold));CHKERRQ(ierr); ierr = PetscMalloc1(pipefcg->mmax+1,&(pipefcg->chunksizes));CHKERRQ(ierr); ierr = PetscMalloc3(pipefcg->mmax+2,&(pipefcg->dots),pipefcg->mmax+1,&(pipefcg->etas),pipefcg->mmax+2,&(pipefcg->redux));CHKERRQ(ierr); /* If the requested number of preallocated vectors is greater than mmax reduce nprealloc */ if(pipefcg->nprealloc > pipefcg->mmax+1){ ierr = PetscInfo2(NULL,"Requested nprealloc=%d is greater than m_max+1=%d. Resetting nprealloc = m_max+1.\n",pipefcg->nprealloc, pipefcg->mmax+1);CHKERRQ(ierr); } /* Preallocate additional work vectors */ ierr = KSPAllocateVectors_PIPEFCG(ksp,pipefcg->nprealloc,pipefcg->nprealloc);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)ksp,(pipefcg->mmax+1)*4*sizeof(Vec*)+(pipefcg->mmax+1)*4*sizeof(Vec**)+(pipefcg->mmax+1)*4*sizeof(Vec*)+ (pipefcg->mmax+1)*sizeof(PetscInt)+(pipefcg->mmax+2)*sizeof(Vec*)+(pipefcg->mmax+2)*sizeof(PetscScalar)+(pipefcg->mmax+1)*sizeof(PetscReal));CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode KSPSetUp_GROPPCG(KSP ksp) { PetscErrorCode ierr; PetscFunctionBegin; ierr = KSPSetWorkVecs(ksp,6);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode KSPSetUp_SYMMLQ(KSP ksp) { PetscErrorCode ierr; PetscFunctionBegin; ierr = KSPSetWorkVecs(ksp,9);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode KSPSetUp_CGS(KSP ksp) { PetscErrorCode ierr; PetscFunctionBegin; ierr = KSPSetWorkVecs(ksp,7);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode KSPSetUp_TCQMR(KSP ksp) { PetscErrorCode ierr; PetscFunctionBegin; if (ksp->pc_side == PC_SYMMETRIC) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"no symmetric preconditioning for KSPTCQMR"); ierr = KSPSetWorkVecs(ksp,TCQMR_VECS);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode KSPSetUp_QCG(KSP ksp) { PetscErrorCode ierr; PetscFunctionBegin; /* Get work vectors from user code */ ierr = KSPSetWorkVecs(ksp,7);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode KSPSetUp_PIPECG(KSP ksp) { PetscErrorCode ierr; PetscFunctionBegin; /* get work vectors needed by PIPECG */ ierr = KSPSetWorkVecs(ksp,9);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode KSPSetUp_MINRES(KSP ksp) { PetscErrorCode ierr; PetscFunctionBegin; if (ksp->pc_side == PC_RIGHT) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"No right preconditioning for KSPMINRES"); else if (ksp->pc_side == PC_SYMMETRIC) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"No symmetric preconditioning for KSPMINRES"); ierr = KSPSetWorkVecs(ksp,9);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode KSPSetUp_CR(KSP ksp) { PetscErrorCode ierr; PetscFunctionBegin; if (ksp->pc_side == PC_RIGHT) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"no right preconditioning for KSPCR"); else if (ksp->pc_side == PC_SYMMETRIC) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"no symmetric preconditioning for KSPCR"); ierr = KSPSetWorkVecs(ksp,6);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode KSPSetUp_BiCG(KSP ksp) { PetscErrorCode ierr; PetscFunctionBegin; /* check user parameters and functions */ if (ksp->pc_side == PC_RIGHT) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"no right preconditioning for KSPBiCG"); else if (ksp->pc_side == PC_SYMMETRIC) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"no symmetric preconditioning for KSPBiCG"); ierr = KSPSetWorkVecs(ksp,6);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode KSPSetUp_IBCGS(KSP ksp) { PetscErrorCode ierr; PetscBool diagonalscale; PetscFunctionBegin; ierr = PCGetDiagonalScale(ksp->pc,&diagonalscale);CHKERRQ(ierr); if (diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Krylov method %s does not support diagonal scaling",((PetscObject)ksp)->type_name); ierr = KSPSetWorkVecs(ksp,9);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode KSPSetUp_Chebyshev(KSP ksp) { KSP_Chebyshev *cheb = (KSP_Chebyshev*)ksp->data; PetscErrorCode ierr; PetscFunctionBegin; ierr = KSPSetWorkVecs(ksp,3);CHKERRQ(ierr); if ((cheb->emin == 0. || cheb->emax == 0.) && !cheb->kspest) { /* We need to estimate eigenvalues */ ierr = KSPChebyshevEstEigSet(ksp,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode KSPSetUp_STCG(KSP ksp) { PetscErrorCode ierr; /***************************************************************************/ /* Set work vectors needed by conjugate gradient method and allocate */ /***************************************************************************/ PetscFunctionBegin; ierr = KSPSetWorkVecs(ksp, 3);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode KSPSetUp_BCGSL(KSP ksp) { KSP_BCGSL *bcgsl = (KSP_BCGSL*)ksp->data; PetscInt ell = bcgsl->ell,ldMZ = ell+1; PetscErrorCode ierr; PetscFunctionBegin; ierr = KSPSetWorkVecs(ksp, 6+2*ell);CHKERRQ(ierr); ierr = PetscMalloc5(ldMZ,PetscScalar,&AY0c,ldMZ,PetscScalar,&AYlc,ldMZ,PetscScalar,&AYtc,ldMZ*ldMZ,PetscScalar,&MZa,ldMZ*ldMZ,PetscScalar,&MZb);CHKERRQ(ierr); ierr = PetscBLASIntCast(5*ell,&bcgsl->lwork);CHKERRQ(ierr); ierr = PetscMalloc5(bcgsl->lwork,PetscScalar,&bcgsl->work,ell,PetscReal,&bcgsl->s,ell*ell,PetscScalar,&bcgsl->u,ell*ell,PetscScalar,&bcgsl->v,5*ell,PetscReal,&bcgsl->realwork);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode KSPSetUp_Chebyshev(KSP ksp) { KSP_Chebyshev *cheb = (KSP_Chebyshev*)ksp->data; PetscErrorCode ierr; PetscFunctionBegin; ierr = KSPSetWorkVecs(ksp,3);CHKERRQ(ierr); if (cheb->emin == 0. || cheb->emax == 0.) { /* We need to estimate eigenvalues */ ierr = KSPChebyshevSetEstimateEigenvalues(ksp,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); /* Enable runtime options for cheb->kspest: KSPChebyshevSetEstimateEigenvalues() creates cheb->kspest, but does not call KSPSetFromOptions(cheb->kspest)! */ ierr = KSPSetFromOptions(cheb->kspest);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode KSPSetUp_LCD(KSP ksp) { KSP_LCD *lcd = (KSP_LCD*)ksp->data; PetscErrorCode ierr; PetscInt restart = lcd->restart; PetscFunctionBegin; /* get work vectors needed by LCD */ ierr = KSPSetWorkVecs(ksp,2);CHKERRQ(ierr); ierr = VecDuplicateVecs(ksp->work[0],restart+1,&lcd->P);CHKERRQ(ierr); ierr = VecDuplicateVecs(ksp->work[0], restart + 1, &lcd->Q);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)ksp,2*(restart+2)*sizeof(Vec));CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode KSPSetUp_CGNE(KSP ksp) { KSP_CG *cgP = (KSP_CG*)ksp->data; PetscErrorCode ierr; PetscInt maxit = ksp->max_it; PetscFunctionBegin; /* get work vectors needed by CGNE */ ierr = KSPSetWorkVecs(ksp,4);CHKERRQ(ierr); /* If user requested computations of eigenvalues then allocate work work space needed */ if (ksp->calc_sings) { /* get space to store tridiagonal matrix for Lanczos */ ierr = PetscMalloc4(maxit+1,&cgP->e,maxit+1,&cgP->d,maxit+1,&cgP->ee,maxit+1,&cgP->dd);CHKERRQ(ierr); ierr = PetscLogObjectMemory((PetscObject)ksp,2*(maxit+1)*(sizeof(PetscScalar)+sizeof(PetscReal)));CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode KSPSolve_Richardson(KSP ksp) { PetscErrorCode ierr; PetscInt i,maxit; PetscReal rnorm = 0.0,abr; PetscScalar scale,rdot; Vec x,b,r,z,w = NULL,y = NULL; PetscInt xs, ws; Mat Amat,Pmat; KSP_Richardson *richardsonP = (KSP_Richardson*)ksp->data; PetscBool exists,diagonalscale; PetscFunctionBegin; ierr = PCGetDiagonalScale(ksp->pc,&diagonalscale);CHKERRQ(ierr); if (diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Krylov method %s does not support diagonal scaling",((PetscObject)ksp)->type_name); ksp->its = 0; ierr = PCGetOperators(ksp->pc,&Amat,&Pmat);CHKERRQ(ierr); x = ksp->vec_sol; b = ksp->vec_rhs; ierr = VecGetSize(x,&xs);CHKERRQ(ierr); ierr = VecGetSize(ksp->work[0],&ws);CHKERRQ(ierr); if (xs != ws) { if (richardsonP->selfscale) { ierr = KSPSetWorkVecs(ksp,4);CHKERRQ(ierr); } else { ierr = KSPSetWorkVecs(ksp,2);CHKERRQ(ierr); } } r = ksp->work[0]; z = ksp->work[1]; if (richardsonP->selfscale) { w = ksp->work[2]; y = ksp->work[3]; } maxit = ksp->max_it; /* if user has provided fast Richardson code use that */ ierr = PCApplyRichardsonExists(ksp->pc,&exists);CHKERRQ(ierr); if (exists && !ksp->numbermonitors && !ksp->transpose_solve & !ksp->nullsp) { PCRichardsonConvergedReason reason; ierr = PCApplyRichardson(ksp->pc,b,x,r,ksp->rtol,ksp->abstol,ksp->divtol,maxit,ksp->guess_zero,&ksp->its,&reason);CHKERRQ(ierr); ksp->reason = (KSPConvergedReason)reason; PetscFunctionReturn(0); } scale = richardsonP->scale; if (!ksp->guess_zero) { /* r <- b - A x */ ierr = KSP_MatMult(ksp,Amat,x,r);CHKERRQ(ierr); ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); } else { ierr = VecCopy(b,r);CHKERRQ(ierr); } ksp->its = 0; if (richardsonP->selfscale) { ierr = KSP_PCApply(ksp,r,z);CHKERRQ(ierr); /* z <- B r */ for (i=0; i<maxit; i++) { if (ksp->normtype == KSP_NORM_UNPRECONDITIONED) { ierr = VecNorm(r,NORM_2,&rnorm);CHKERRQ(ierr); /* rnorm <- r'*r */ ierr = KSPMonitor(ksp,i,rnorm);CHKERRQ(ierr); ksp->rnorm = rnorm; ierr = KSPLogResidualHistory(ksp,rnorm);CHKERRQ(ierr); ierr = (*ksp->converged)(ksp,i,rnorm,&ksp->reason,ksp->cnvP);CHKERRQ(ierr); if (ksp->reason) break; } else if (ksp->normtype == KSP_NORM_PRECONDITIONED) { ierr = VecNorm(z,NORM_2,&rnorm);CHKERRQ(ierr); /* rnorm <- z'*z */ ierr = KSPMonitor(ksp,i,rnorm);CHKERRQ(ierr); ksp->rnorm = rnorm; ierr = KSPLogResidualHistory(ksp,rnorm);CHKERRQ(ierr); ierr = (*ksp->converged)(ksp,i,rnorm,&ksp->reason,ksp->cnvP);CHKERRQ(ierr); if (ksp->reason) break; } ierr = KSP_PCApplyBAorAB(ksp,z,y,w);CHKERRQ(ierr); /* y = BAz = BABr */ ierr = VecDotNorm2(z,y,&rdot,&abr);CHKERRQ(ierr); /* rdot = (Br)^T(BABR); abr = (BABr)^T (BABr) */ scale = rdot/abr; ierr = PetscInfo1(ksp,"Self-scale factor %g\n",(double)PetscRealPart(scale));CHKERRQ(ierr); ierr = VecAXPY(x,scale,z);CHKERRQ(ierr); /* x <- x + scale z */ ierr = VecAXPY(r,-scale,w);CHKERRQ(ierr); /* r <- r - scale*Az */ ierr = VecAXPY(z,-scale,y);CHKERRQ(ierr); /* z <- z - scale*y */ ksp->its++; } } else { for (i=0; i<maxit; i++) { if (ksp->normtype == KSP_NORM_UNPRECONDITIONED) { ierr = VecNorm(r,NORM_2,&rnorm);CHKERRQ(ierr); /* rnorm <- r'*r */ ierr = KSPMonitor(ksp,i,rnorm);CHKERRQ(ierr); ksp->rnorm = rnorm; ierr = KSPLogResidualHistory(ksp,rnorm);CHKERRQ(ierr); ierr = (*ksp->converged)(ksp,i,rnorm,&ksp->reason,ksp->cnvP);CHKERRQ(ierr); if (ksp->reason) break; } ierr = KSP_PCApply(ksp,r,z);CHKERRQ(ierr); /* z <- B r */ if (ksp->normtype == KSP_NORM_PRECONDITIONED) { ierr = VecNorm(z,NORM_2,&rnorm);CHKERRQ(ierr); /* rnorm <- z'*z */ ierr = KSPMonitor(ksp,i,rnorm);CHKERRQ(ierr); ksp->rnorm = rnorm; ierr = KSPLogResidualHistory(ksp,rnorm);CHKERRQ(ierr); ierr = (*ksp->converged)(ksp,i,rnorm,&ksp->reason,ksp->cnvP);CHKERRQ(ierr); if (ksp->reason) break; } ierr = VecAXPY(x,scale,z);CHKERRQ(ierr); /* x <- x + scale z */ ksp->its++; if (i+1 < maxit || ksp->normtype != KSP_NORM_NONE) { ierr = KSP_MatMult(ksp,Amat,x,r);CHKERRQ(ierr); /* r <- b - Ax */ ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr); } } } if (!ksp->reason) { if (ksp->normtype != KSP_NORM_NONE) { if (ksp->normtype == KSP_NORM_UNPRECONDITIONED) { ierr = VecNorm(r,NORM_2,&rnorm);CHKERRQ(ierr); /* rnorm <- r'*r */ } else { ierr = KSP_PCApply(ksp,r,z);CHKERRQ(ierr); /* z <- B r */ ierr = VecNorm(z,NORM_2,&rnorm);CHKERRQ(ierr); /* rnorm <- z'*z */ } ksp->rnorm = rnorm; ierr = KSPLogResidualHistory(ksp,rnorm);CHKERRQ(ierr); ierr = KSPMonitor(ksp,i,rnorm);CHKERRQ(ierr); } if (ksp->its >= ksp->max_it) { if (ksp->normtype != KSP_NORM_NONE) { ierr = (*ksp->converged)(ksp,i,rnorm,&ksp->reason,ksp->cnvP);CHKERRQ(ierr); if (!ksp->reason) ksp->reason = KSP_DIVERGED_ITS; } else { ksp->reason = KSP_CONVERGED_ITS; } } } PetscFunctionReturn(0); }