本文整理汇总了C++中PCGetOperators函数的典型用法代码示例。如果您正苦于以下问题:C++ PCGetOperators函数的具体用法?C++ PCGetOperators怎么用?C++ PCGetOperators使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了PCGetOperators函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: MatGetVecs
/*@C
KSPGetVecs - Gets a number of work vectors.
Input Parameters:
+ ksp - iterative context
. rightn - number of right work vectors
- leftn - number of left work vectors to allocate
Output Parameter:
+ right - the array of vectors created
- left - the array of left vectors
Note: The right vector has as many elements as the matrix has columns. The left
vector has as many elements as the matrix has rows.
Level: advanced
.seealso: MatGetVecs()
@*/
PetscErrorCode KSPGetVecs(KSP ksp,PetscInt rightn, Vec **right,PetscInt leftn,Vec **left)
{
PetscErrorCode ierr;
Vec vecr,vecl;
PetscFunctionBegin;
if (rightn) {
if (!right) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_INCOMP,"You asked for right vectors but did not pass a pointer to hold them");
if (ksp->vec_sol) vecr = ksp->vec_sol;
else {
if (ksp->dm) {
ierr = DMGetGlobalVector(ksp->dm,&vecr);CHKERRQ(ierr);
} else {
Mat mat;
if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
ierr = PCGetOperators(ksp->pc,&mat,NULL,NULL);CHKERRQ(ierr);
ierr = MatGetVecs(mat,&vecr,NULL);CHKERRQ(ierr);
}
}
ierr = VecDuplicateVecs(vecr,rightn,right);CHKERRQ(ierr);
if (!ksp->vec_sol) {
if (ksp->dm) {
ierr = DMRestoreGlobalVector(ksp->dm,&vecr);CHKERRQ(ierr);
} else {
ierr = VecDestroy(&vecr);CHKERRQ(ierr);
}
}
}
if (leftn) {
if (!left) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_INCOMP,"You asked for left vectors but did not pass a pointer to hold them");
if (ksp->vec_rhs) vecl = ksp->vec_rhs;
else {
if (ksp->dm) {
ierr = DMGetGlobalVector(ksp->dm,&vecl);CHKERRQ(ierr);
} else {
Mat mat;
if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
ierr = PCGetOperators(ksp->pc,&mat,NULL,NULL);CHKERRQ(ierr);
ierr = MatGetVecs(mat,NULL,&vecl);CHKERRQ(ierr);
}
}
ierr = VecDuplicateVecs(vecl,leftn,left);CHKERRQ(ierr);
if (!ksp->vec_rhs) {
if (ksp->dm) {
ierr = DMRestoreGlobalVector(ksp->dm,&vecl);CHKERRQ(ierr);
} else {
ierr = VecDestroy(&vecl);CHKERRQ(ierr);
}
}
}
PetscFunctionReturn(0);
}
示例2: KSPInitialResidual
PetscErrorCode KSPInitialResidual(KSP ksp,Vec vsoln,Vec vt1,Vec vt2,Vec vres,Vec vb)
{
Mat Amat,Pmat;
PetscErrorCode ierr;
PetscFunctionBegin;
PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
PetscValidHeaderSpecific(vsoln,VEC_CLASSID,2);
PetscValidHeaderSpecific(vres,VEC_CLASSID,5);
PetscValidHeaderSpecific(vb,VEC_CLASSID,6);
if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
ierr = PCGetOperators(ksp->pc,&Amat,&Pmat);CHKERRQ(ierr);
if (!ksp->guess_zero) {
/* skip right scaling since current guess already has it */
ierr = KSP_MatMult(ksp,Amat,vsoln,vt1);CHKERRQ(ierr);
ierr = VecCopy(vb,vt2);CHKERRQ(ierr);
ierr = VecAXPY(vt2,-1.0,vt1);CHKERRQ(ierr);
ierr = (ksp->pc_side == PC_RIGHT) ? (VecCopy(vt2,vres)) : (KSP_PCApply(ksp,vt2,vres));CHKERRQ(ierr);
ierr = PCDiagonalScaleLeft(ksp->pc,vres,vres);CHKERRQ(ierr);
} else {
ierr = VecCopy(vb,vt2);CHKERRQ(ierr);
if (ksp->pc_side == PC_RIGHT) {
ierr = PCDiagonalScaleLeft(ksp->pc,vb,vres);CHKERRQ(ierr);
} else if (ksp->pc_side == PC_LEFT) {
ierr = KSP_PCApply(ksp,vb,vres);CHKERRQ(ierr);
ierr = PCDiagonalScaleLeft(ksp->pc,vres,vres);CHKERRQ(ierr);
} else if (ksp->pc_side == PC_SYMMETRIC) {
ierr = PCApplySymmetricLeft(ksp->pc, vb, vres);CHKERRQ(ierr);
} else SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP, "Invalid preconditioning side %d", (int)ksp->pc_side);
}
PetscFunctionReturn(0);
}
示例3: PCSetUp_Exotic
PetscErrorCode PCSetUp_Exotic(PC pc)
{
PetscErrorCode ierr;
Mat A;
PC_MG *mg = (PC_MG*)pc->data;
PC_Exotic *ex = (PC_Exotic*) mg->innerctx;
MatReuse reuse = (ex->P) ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX;
PetscFunctionBegin;
if (!pc->dm) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Need to call PCSetDM() before using this PC");
ierr = PCGetOperators(pc,NULL,&A);
CHKERRQ(ierr);
if (ex->type == PC_EXOTIC_FACE) {
ierr = DMDAGetFaceInterpolation(pc->dm,ex,A,reuse,&ex->P);
CHKERRQ(ierr);
} else if (ex->type == PC_EXOTIC_WIREBASKET) {
ierr = DMDAGetWireBasketInterpolation(pc->dm,ex,A,reuse,&ex->P);
CHKERRQ(ierr);
} else SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Unknown exotic coarse space %d",ex->type);
ierr = PCMGSetInterpolation(pc,1,ex->P);
CHKERRQ(ierr);
/* if PC has attached DM we must remove it or the PCMG will use it to compute incorrect sized vectors and interpolations */
ierr = PCSetDM(pc,NULL);
CHKERRQ(ierr);
ierr = PCSetUp_MG(pc);
CHKERRQ(ierr);
PetscFunctionReturn(0);
}
示例4: pcgetoperators_
PETSC_EXTERN void PETSC_STDCALL pcgetoperators_(PC *pc,Mat *mat,Mat *pmat,MatStructure *flag,PetscErrorCode *ierr)
{
CHKFORTRANNULLOBJECT(mat);
CHKFORTRANNULLOBJECT(pmat);
CHKFORTRANNULLINTEGER(flag);
*ierr = PCGetOperators(*pc,mat,pmat,flag);
}
示例5: KSPComputeEigenvaluesExplicitly
/*@
KSPComputeExplicitOperator - Computes the explicit preconditioned operator.
Collective on KSP
Input Parameter:
. ksp - the Krylov subspace context
Output Parameter:
. mat - the explict preconditioned operator
Notes:
This computation is done by applying the operators to columns of the
identity matrix.
Currently, this routine uses a dense matrix format when 1 processor
is used and a sparse format otherwise. This routine is costly in general,
and is recommended for use only with relatively small systems.
Level: advanced
.keywords: KSP, compute, explicit, operator
.seealso: KSPComputeEigenvaluesExplicitly(), PCComputeExplicitOperator()
@*/
PetscErrorCode KSPComputeExplicitOperator(KSP ksp,Mat *mat)
{
Vec in,out;
PetscErrorCode ierr;
PetscMPIInt size;
PetscInt i,M,m,*rows,start,end;
Mat A;
MPI_Comm comm;
PetscScalar *array,one = 1.0;
PetscFunctionBegin;
PetscValidHeaderSpecific(ksp,KSP_CLASSID,1);
PetscValidPointer(mat,2);
comm = ((PetscObject)ksp)->comm;
ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
ierr = VecDuplicate(ksp->vec_sol,&in);CHKERRQ(ierr);
ierr = VecDuplicate(ksp->vec_sol,&out);CHKERRQ(ierr);
ierr = VecGetSize(in,&M);CHKERRQ(ierr);
ierr = VecGetLocalSize(in,&m);CHKERRQ(ierr);
ierr = VecGetOwnershipRange(in,&start,&end);CHKERRQ(ierr);
ierr = PetscMalloc(m*sizeof(PetscInt),&rows);CHKERRQ(ierr);
for (i=0; i<m; i++) {rows[i] = start + i;}
ierr = MatCreate(comm,mat);CHKERRQ(ierr);
ierr = MatSetSizes(*mat,m,m,M,M);CHKERRQ(ierr);
if (size == 1) {
ierr = MatSetType(*mat,MATSEQDENSE);CHKERRQ(ierr);
ierr = MatSeqDenseSetPreallocation(*mat,PETSC_NULL);CHKERRQ(ierr);
} else {
ierr = MatSetType(*mat,MATMPIAIJ);CHKERRQ(ierr);
ierr = MatMPIAIJSetPreallocation(*mat,0,PETSC_NULL,0,PETSC_NULL);CHKERRQ(ierr);
}
ierr = MatSetOption(*mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
ierr = PCGetOperators(ksp->pc,&A,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
for (i=0; i<M; i++) {
ierr = VecSet(in,0.0);CHKERRQ(ierr);
ierr = VecSetValues(in,1,&i,&one,INSERT_VALUES);CHKERRQ(ierr);
ierr = VecAssemblyBegin(in);CHKERRQ(ierr);
ierr = VecAssemblyEnd(in);CHKERRQ(ierr);
ierr = KSP_MatMult(ksp,A,in,out);CHKERRQ(ierr);
ierr = KSP_PCApply(ksp,out,in);CHKERRQ(ierr);
ierr = VecGetArray(in,&array);CHKERRQ(ierr);
ierr = MatSetValues(*mat,m,rows,1,&i,array,INSERT_VALUES);CHKERRQ(ierr);
ierr = VecRestoreArray(in,&array);CHKERRQ(ierr);
}
ierr = PetscFree(rows);CHKERRQ(ierr);
ierr = VecDestroy(&in);CHKERRQ(ierr);
ierr = VecDestroy(&out);CHKERRQ(ierr);
ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
PetscFunctionReturn(0);
}
示例6: ApplyPCPrecPETSCGen
static void ApplyPCPrecPETSCGen(void *x, PRIMME_INT *ldx, void *y,
PRIMME_INT *ldy, int *blockSize, int trans, PC *pc, MPI_Comm comm) {
int i;
Vec xvec, yvec;
Mat matrix;
PetscErrorCode ierr;
PetscInt mLocal, nLocal;
ierr = PCGetOperators(pc[0],&matrix,NULL); CHKERRABORT(comm, ierr);
assert(sizeof(PetscScalar) == sizeof(SCALAR));
ierr = MatGetLocalSize(matrix, &mLocal, &nLocal); CHKERRABORT(comm, ierr);
assert(mLocal == nLocal && nLocal <= *ldx && mLocal <= *ldy);
#if PETSC_VERSION_LT(3,6,0)
ierr = MatGetVecs(matrix, &xvec, &yvec); CHKERRABORT(comm, ierr);
#else
ierr = MatCreateVecs(matrix, &xvec, &yvec); CHKERRABORT(comm, ierr);
#endif
for (i=0; i<*blockSize; i++) {
ierr = VecPlaceArray(xvec, ((SCALAR*)x) + (*ldx)*i); CHKERRABORT(comm, ierr);
ierr = VecPlaceArray(yvec, ((SCALAR*)y) + (*ldy)*i); CHKERRABORT(comm, ierr);
if (trans == 0) {
ierr = PCApply(*pc, xvec, yvec); CHKERRABORT(comm, ierr);
} else if (pc[1]) {
ierr = PCApply(pc[1], xvec, yvec); CHKERRABORT(comm, ierr);
} else {
ierr = PCApplyTranspose(pc[0], xvec, yvec);
}
ierr = VecResetArray(xvec); CHKERRABORT(comm, ierr);
ierr = VecResetArray(yvec); CHKERRABORT(comm, ierr);
}
ierr = VecDestroy(&xvec); CHKERRABORT(comm, ierr);
ierr = VecDestroy(&yvec); CHKERRABORT(comm, ierr);
}
示例7: KSPComputeShifts_GMRES
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);
}
示例8: KSPBuildSolutionDefault
/*
KSPBuildResidualDefault - Default code to compute the residual.
Input Parameters:
. ksp - iterative context
. t - pointer to temporary vector
. v - pointer to user vector
Output Parameter:
. V - pointer to a vector containing the residual
Level: advanced
Developers Note: This is PETSC_EXTERN because it may be used by user written plugin KSP implementations
.keywords: KSP, build, residual, default
.seealso: KSPBuildSolutionDefault()
*/
PetscErrorCode KSPBuildResidualDefault(KSP ksp,Vec t,Vec v,Vec *V)
{
PetscErrorCode ierr;
Mat Amat,Pmat;
PetscFunctionBegin;
if (!ksp->pc) {ierr = KSPGetPC(ksp,&ksp->pc);CHKERRQ(ierr);}
ierr = PCGetOperators(ksp->pc,&Amat,&Pmat);CHKERRQ(ierr);
ierr = KSPBuildSolution(ksp,t,NULL);CHKERRQ(ierr);
ierr = KSP_MatMult(ksp,Amat,t,v);CHKERRQ(ierr);
ierr = VecAYPX(v,-1.0,ksp->vec_rhs);CHKERRQ(ierr);
*V = v;
PetscFunctionReturn(0);
}
示例9: KSPLSQRGetArnorm
PetscErrorCode KSPLSQRGetArnorm(KSP ksp,PetscReal *arnorm, PetscReal *rhs_norm, PetscReal *anorm)
{
KSP_LSQR *lsqr = (KSP_LSQR*)ksp->data;
PetscErrorCode ierr;
PetscFunctionBegin;
*arnorm = lsqr->arnorm;
if (anorm) {
if (lsqr->anorm < 0.0) {
PC pc;
Mat Amat;
ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
ierr = PCGetOperators(pc,&Amat,NULL,NULL);CHKERRQ(ierr);
ierr = MatNorm(Amat,NORM_FROBENIUS,&lsqr->anorm);CHKERRQ(ierr);
}
*anorm = lsqr->anorm;
}
if (rhs_norm) *rhs_norm = lsqr->rhs_norm;
PetscFunctionReturn(0);
}
示例10: PCSetUp_PARMS
static PetscErrorCode PCSetUp_PARMS(PC pc)
{
Mat pmat;
PC_PARMS *parms = (PC_PARMS*)pc->data;
const PetscInt *mapptr0;
PetscInt n, lsize, low, high, i, pos, ncols, length;
int *maptmp, *mapptr, *ia, *ja, *ja1, *im;
PetscScalar *aa, *aa1;
const PetscInt *cols;
PetscInt meth[8];
const PetscScalar *values;
PetscErrorCode ierr;
MatInfo matinfo;
PetscMPIInt rank, npro;
PetscFunctionBegin;
/* Get preconditioner matrix from PETSc and setup pARMS structs */
ierr = PCGetOperators(pc,PETSC_NULL,&pmat,PETSC_NULL);CHKERRQ(ierr);
MPI_Comm_size(((PetscObject)pmat)->comm,&npro);
MPI_Comm_rank(((PetscObject)pmat)->comm,&rank);
ierr = MatGetSize(pmat,&n,PETSC_NULL);CHKERRQ(ierr);
ierr = PetscMalloc((npro+1)*sizeof(int),&mapptr);CHKERRQ(ierr);
ierr = PetscMalloc(n*sizeof(int),&maptmp);CHKERRQ(ierr);
ierr = MatGetOwnershipRanges(pmat,&mapptr0);CHKERRQ(ierr);
low = mapptr0[rank];
high = mapptr0[rank+1];
lsize = high - low;
for (i=0; i<npro+1; i++)
mapptr[i] = mapptr0[i]+1;
for (i = 0; i<n; i++)
maptmp[i] = i+1;
/* if created, destroy the previous map */
if (parms->map) {
parms_MapFree(&parms->map);
parms->map = PETSC_NULL;
}
/* create pARMS map object */
parms_MapCreateFromPtr(&parms->map,(int)n,maptmp,mapptr,((PetscObject)pmat)->comm,1,NONINTERLACED);
/* if created, destroy the previous pARMS matrix */
if (parms->A) {
parms_MatFree(&parms->A);
parms->A = PETSC_NULL;
}
/* create pARMS mat object */
parms_MatCreate(&parms->A,parms->map);
/* setup and copy csr data structure for pARMS */
ierr = PetscMalloc((lsize+1)*sizeof(int),&ia);CHKERRQ(ierr);
ia[0] = 1;
ierr = MatGetInfo(pmat,MAT_LOCAL,&matinfo);CHKERRQ(ierr);
length = matinfo.nz_used;
ierr = PetscMalloc(length*sizeof(int),&ja);CHKERRQ(ierr);
ierr = PetscMalloc(length*sizeof(PetscScalar),&aa);CHKERRQ(ierr);
for (i = low; i<high; i++) {
pos = ia[i-low]-1;
ierr = MatGetRow(pmat,i,&ncols,&cols,&values);CHKERRQ(ierr);
ia[i-low+1] = ia[i-low] + ncols;
if (ia[i-low+1] >= length) {
length += ncols;
ierr = PetscMalloc(length*sizeof(int),&ja1);CHKERRQ(ierr);
ierr = PetscMemcpy(ja1,ja,(ia[i-low]-1)*sizeof(int));CHKERRQ(ierr);
ierr = PetscFree(ja);CHKERRQ(ierr);
ja = ja1;
ierr = PetscMalloc(length*sizeof(PetscScalar),&aa1);CHKERRQ(ierr);
ierr = PetscMemcpy(aa1,aa,(ia[i-low]-1)*sizeof(PetscScalar));CHKERRQ(ierr);
ierr = PetscFree(aa);CHKERRQ(ierr);
aa = aa1;
}
ierr = PetscMemcpy(&ja[pos],cols,ncols*sizeof(int));CHKERRQ(ierr);
ierr = PetscMemcpy(&aa[pos],values,ncols*sizeof(PetscScalar));CHKERRQ(ierr);
ierr = MatRestoreRow(pmat,i,&ncols,&cols,&values);CHKERRQ(ierr);
}
/* csr info is for local matrix so initialize im[] locally */
ierr = PetscMalloc(lsize*sizeof(int),&im);CHKERRQ(ierr);
ierr = PetscMemcpy(im,&maptmp[mapptr[rank]-1],lsize*sizeof(int));CHKERRQ(ierr);
/* 1-based indexing */
for (i=0; i<ia[lsize]-1; i++)
ja[i] = ja[i]+1;
/* Now copy csr matrix to parms_mat object */
parms_MatSetValues(parms->A,(int)lsize,im,ia,ja,aa,INSERT);
/* free memory */
ierr = PetscFree(maptmp);CHKERRQ(ierr);
ierr = PetscFree(mapptr);CHKERRQ(ierr);
ierr = PetscFree(aa);CHKERRQ(ierr);
ierr = PetscFree(ja);CHKERRQ(ierr);
ierr = PetscFree(ia);CHKERRQ(ierr);
ierr = PetscFree(im);CHKERRQ(ierr);
//.........这里部分代码省略.........
示例11: KSPSolve_LSQR
static PetscErrorCode KSPSolve_LSQR(KSP ksp)
{
PetscErrorCode ierr;
PetscInt i,size1,size2;
PetscScalar rho,rhobar,phi,phibar,theta,c,s,tmp,tau;
PetscReal beta,alpha,rnorm;
Vec X,B,V,V1,U,U1,TMP,W,W2,SE,Z = NULL;
Mat Amat,Pmat;
MatStructure pflag;
KSP_LSQR *lsqr = (KSP_LSQR*)ksp->data;
PetscBool diagonalscale,nopreconditioner;
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 = PCGetOperators(ksp->pc,&Amat,&Pmat,&pflag);CHKERRQ(ierr);
ierr = PetscObjectTypeCompare((PetscObject)ksp->pc,PCNONE,&nopreconditioner);CHKERRQ(ierr);
/* nopreconditioner =PETSC_FALSE; */
/* Calculate norm of right hand side */
ierr = VecNorm(ksp->vec_rhs,NORM_2,&lsqr->rhs_norm);CHKERRQ(ierr);
/* mark norm of matrix with negative number to indicate it has not yet been computed */
lsqr->anorm = -1.0;
/* vectors of length m, where system size is mxn */
B = ksp->vec_rhs;
U = lsqr->vwork_m[0];
U1 = lsqr->vwork_m[1];
/* vectors of length n */
X = ksp->vec_sol;
W = lsqr->vwork_n[0];
V = lsqr->vwork_n[1];
V1 = lsqr->vwork_n[2];
W2 = lsqr->vwork_n[3];
if (!nopreconditioner) Z = lsqr->vwork_n[4];
/* standard error vector */
SE = lsqr->se;
if (SE) {
ierr = VecGetSize(SE,&size1);CHKERRQ(ierr);
ierr = VecGetSize(X,&size2);CHKERRQ(ierr);
if (size1 != size2) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Standard error vector (size %d) does not match solution vector (size %d)",size1,size2);
ierr = VecSet(SE,0.0);CHKERRQ(ierr);
}
/* Compute initial residual, temporarily use work vector u */
if (!ksp->guess_zero) {
ierr = KSP_MatMult(ksp,Amat,X,U);CHKERRQ(ierr); /* u <- b - Ax */
ierr = VecAYPX(U,-1.0,B);CHKERRQ(ierr);
} else {
ierr = VecCopy(B,U);CHKERRQ(ierr); /* u <- b (x is 0) */
}
/* Test for nothing to do */
ierr = VecNorm(U,NORM_2,&rnorm);CHKERRQ(ierr);
ierr = PetscObjectAMSTakeAccess((PetscObject)ksp);CHKERRQ(ierr);
ksp->its = 0;
ksp->rnorm = rnorm;
ierr = PetscObjectAMSGrantAccess((PetscObject)ksp);CHKERRQ(ierr);
ierr = KSPLogResidualHistory(ksp,rnorm);CHKERRQ(ierr);
ierr = KSPMonitor(ksp,0,rnorm);CHKERRQ(ierr);
ierr = (*ksp->converged)(ksp,0,rnorm,&ksp->reason,ksp->cnvP);CHKERRQ(ierr);
if (ksp->reason) PetscFunctionReturn(0);
beta = rnorm;
ierr = VecScale(U,1.0/beta);CHKERRQ(ierr);
ierr = KSP_MatMultTranspose(ksp,Amat,U,V);CHKERRQ(ierr);
if (nopreconditioner) {
ierr = VecNorm(V,NORM_2,&alpha);CHKERRQ(ierr);
} else {
ierr = PCApply(ksp->pc,V,Z);CHKERRQ(ierr);
ierr = VecDotRealPart(V,Z,&alpha);CHKERRQ(ierr);
if (alpha <= 0.0) {
ksp->reason = KSP_DIVERGED_BREAKDOWN;
PetscFunctionReturn(0);
}
alpha = PetscSqrtReal(alpha);
ierr = VecScale(Z,1.0/alpha);CHKERRQ(ierr);
}
ierr = VecScale(V,1.0/alpha);CHKERRQ(ierr);
if (nopreconditioner) {
ierr = VecCopy(V,W);CHKERRQ(ierr);
} else {
ierr = VecCopy(Z,W);CHKERRQ(ierr);
}
lsqr->arnorm = alpha * beta;
phibar = beta;
rhobar = alpha;
i = 0;
do {
if (nopreconditioner) {
ierr = KSP_MatMult(ksp,Amat,V,U1);CHKERRQ(ierr);
} else {
ierr = KSP_MatMult(ksp,Amat,Z,U1);CHKERRQ(ierr);
}
//.........这里部分代码省略.........
示例12: KSPSolve_SYMMLQ
PetscErrorCode KSPSolve_SYMMLQ(KSP ksp)
{
PetscErrorCode ierr;
PetscInt i;
PetscScalar alpha,beta,ibeta,betaold,beta1,ceta = 0,ceta_oold = 0.0, ceta_old = 0.0,ceta_bar;
PetscScalar c = 1.0,cold=1.0,s=0.0,sold=0.0,coold,soold,rho0,rho1,rho2,rho3;
PetscScalar dp = 0.0;
PetscReal np,s_prod;
Vec X,B,R,Z,U,V,W,UOLD,VOLD,Wbar;
Mat Amat,Pmat;
MatStructure pflag;
KSP_SYMMLQ *symmlq = (KSP_SYMMLQ*)ksp->data;
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);
X = ksp->vec_sol;
B = ksp->vec_rhs;
R = ksp->work[0];
Z = ksp->work[1];
U = ksp->work[2];
V = ksp->work[3];
W = ksp->work[4];
UOLD = ksp->work[5];
VOLD = ksp->work[6];
Wbar = ksp->work[7];
ierr = PCGetOperators(ksp->pc,&Amat,&Pmat,&pflag);CHKERRQ(ierr);
ksp->its = 0;
ierr = VecSet(UOLD,0.0);CHKERRQ(ierr); /* u_old <- zeros; */
ierr = VecCopy(UOLD,VOLD);CHKERRQ(ierr); /* v_old <- u_old; */
ierr = VecCopy(UOLD,W);CHKERRQ(ierr); /* w <- u_old; */
ierr = VecCopy(UOLD,Wbar);CHKERRQ(ierr); /* w_bar <- u_old; */
if (!ksp->guess_zero) {
ierr = KSP_MatMult(ksp,Amat,X,R);CHKERRQ(ierr); /* r <- b - A*x */
ierr = VecAYPX(R,-1.0,B);CHKERRQ(ierr);
} else {
ierr = VecCopy(B,R);CHKERRQ(ierr); /* r <- b (x is 0) */
}
ierr = KSP_PCApply(ksp,R,Z);CHKERRQ(ierr); /* z <- B*r */
ierr = VecDot(R,Z,&dp);CHKERRQ(ierr); /* dp = r'*z; */
if (PetscAbsScalar(dp) < symmlq->haptol) {
ierr = PetscInfo2(ksp,"Detected happy breakdown %G tolerance %G\n",PetscAbsScalar(dp),symmlq->haptol);CHKERRQ(ierr);
ksp->rnorm = 0.0; /* what should we really put here? */
ksp->reason = KSP_CONVERGED_HAPPY_BREAKDOWN; /* bugfix proposed by Lourens ([email protected]) */
PetscFunctionReturn(0);
}
#if !defined(PETSC_USE_COMPLEX)
if (dp < 0.0) {
ksp->reason = KSP_DIVERGED_INDEFINITE_PC;
PetscFunctionReturn(0);
}
#endif
dp = PetscSqrtScalar(dp);
beta = dp; /* beta <- sqrt(r'*z) */
beta1 = beta;
s_prod = PetscAbsScalar(beta1);
ierr = VecCopy(R,V);CHKERRQ(ierr); /* v <- r; */
ierr = VecCopy(Z,U);CHKERRQ(ierr); /* u <- z; */
ibeta = 1.0 / beta;
ierr = VecScale(V,ibeta);CHKERRQ(ierr); /* v <- ibeta*v; */
ierr = VecScale(U,ibeta);CHKERRQ(ierr); /* u <- ibeta*u; */
ierr = VecCopy(U,Wbar);CHKERRQ(ierr); /* w_bar <- u; */
ierr = VecNorm(Z,NORM_2,&np);CHKERRQ(ierr); /* np <- ||z|| */
ierr = KSPLogResidualHistory(ksp,np);CHKERRQ(ierr);
ierr = KSPMonitor(ksp,0,np);CHKERRQ(ierr);
ksp->rnorm = np;
ierr = (*ksp->converged)(ksp,0,np,&ksp->reason,ksp->cnvP);CHKERRQ(ierr); /* test for convergence */
if (ksp->reason) PetscFunctionReturn(0);
i = 0; ceta = 0.;
do {
ksp->its = i+1;
/* Update */
if (ksp->its > 1) {
ierr = VecCopy(V,VOLD);CHKERRQ(ierr); /* v_old <- v; */
ierr = VecCopy(U,UOLD);CHKERRQ(ierr); /* u_old <- u; */
ierr = VecCopy(R,V);CHKERRQ(ierr);
ierr = VecScale(V,1.0/beta);CHKERRQ(ierr); /* v <- ibeta*r; */
ierr = VecCopy(Z,U);CHKERRQ(ierr);
ierr = VecScale(U,1.0/beta);CHKERRQ(ierr); /* u <- ibeta*z; */
ierr = VecCopy(Wbar,W);CHKERRQ(ierr);
ierr = VecScale(W,c);CHKERRQ(ierr);
ierr = VecAXPY(W,s,U);CHKERRQ(ierr); /* w <- c*w_bar + s*u; (w_k) */
ierr = VecScale(Wbar,-s);CHKERRQ(ierr);
ierr = VecAXPY(Wbar,c,U);CHKERRQ(ierr); /* w_bar <- -s*w_bar + c*u; (w_bar_(k+1)) */
ierr = VecAXPY(X,ceta,W);CHKERRQ(ierr); /* x <- x + ceta * w; (xL_k) */
ceta_oold = ceta_old;
ceta_old = ceta;
//.........这里部分代码省略.........
示例13: KSPSolve_Chebyshev
PetscErrorCode KSPSolve_Chebyshev(KSP ksp)
{
KSP_Chebyshev *cheb = (KSP_Chebyshev*)ksp->data;
PetscErrorCode ierr;
PetscInt k,kp1,km1,maxit,ktmp,i;
PetscScalar alpha,omegaprod,mu,omega,Gamma,c[3],scale;
PetscReal rnorm = 0.0;
Vec sol_orig,b,p[3],r;
Mat Amat,Pmat;
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);
if (cheb->kspest && !cheb->estimate_current) {
PetscReal max=0.0,min=0.0;
Vec X,B;
X = ksp->work[0];
if (cheb->random) {
B = ksp->work[1];
ierr = VecSetRandom(B,cheb->random);CHKERRQ(ierr);
} else {
B = ksp->vec_rhs;
}
ierr = KSPSolve(cheb->kspest,B,X);CHKERRQ(ierr);
if (ksp->guess_zero) {
ierr = VecZeroEntries(X);CHKERRQ(ierr);
}
ierr = KSPChebyshevComputeExtremeEigenvalues_Private(cheb->kspest,&min,&max);CHKERRQ(ierr);
cheb->emin = cheb->tform[0]*min + cheb->tform[1]*max;
cheb->emax = cheb->tform[2]*min + cheb->tform[3]*max;
cheb->estimate_current = PETSC_TRUE;
}
ksp->its = 0;
ierr = PCGetOperators(ksp->pc,&Amat,&Pmat);CHKERRQ(ierr);
maxit = ksp->max_it;
/* These three point to the three active solutions, we
rotate these three at each solution update */
km1 = 0; k = 1; kp1 = 2;
sol_orig = ksp->vec_sol; /* ksp->vec_sol will be asigned to rotating vector p[k], thus save its address */
b = ksp->vec_rhs;
p[km1] = sol_orig;
p[k] = ksp->work[0];
p[kp1] = ksp->work[1];
r = ksp->work[2];
/* use scale*B as our preconditioner */
scale = 2.0/(cheb->emax + cheb->emin);
/* -alpha <= scale*lambda(B^{-1}A) <= alpha */
alpha = 1.0 - scale*(cheb->emin);
Gamma = 1.0;
mu = 1.0/alpha;
omegaprod = 2.0/alpha;
c[km1] = 1.0;
c[k] = mu;
if (!ksp->guess_zero) {
ierr = KSP_MatMult(ksp,Amat,p[km1],r);CHKERRQ(ierr); /* r = b - A*p[km1] */
ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
} else {
ierr = VecCopy(b,r);CHKERRQ(ierr);
}
ierr = KSP_PCApply(ksp,r,p[k]);CHKERRQ(ierr); /* p[k] = scale B^{-1}r + p[km1] */
ierr = VecAYPX(p[k],scale,p[km1]);CHKERRQ(ierr);
for (i=0; i<maxit; i++) {
ierr = PetscObjectSAWsTakeAccess((PetscObject)ksp);CHKERRQ(ierr);
ksp->its++;
ierr = PetscObjectSAWsGrantAccess((PetscObject)ksp);CHKERRQ(ierr);
c[kp1] = 2.0*mu*c[k] - c[km1];
omega = omegaprod*c[k]/c[kp1];
ierr = KSP_MatMult(ksp,Amat,p[k],r);CHKERRQ(ierr); /* r = b - Ap[k] */
ierr = VecAYPX(r,-1.0,b);CHKERRQ(ierr);
ierr = KSP_PCApply(ksp,r,p[kp1]);CHKERRQ(ierr); /* p[kp1] = B^{-1}r */
ksp->vec_sol = p[k];
/* calculate residual norm if requested */
if (ksp->normtype != KSP_NORM_NONE || ksp->numbermonitors) {
if (ksp->normtype == KSP_NORM_UNPRECONDITIONED) {
ierr = VecNorm(r,NORM_2,&rnorm);CHKERRQ(ierr);
} else {
ierr = VecNorm(p[kp1],NORM_2,&rnorm);CHKERRQ(ierr);
}
ierr = PetscObjectSAWsTakeAccess((PetscObject)ksp);CHKERRQ(ierr);
ksp->rnorm = rnorm;
ierr = PetscObjectSAWsGrantAccess((PetscObject)ksp);CHKERRQ(ierr);
ierr = KSPLogResidualHistory(ksp,rnorm);CHKERRQ(ierr);
ierr = KSPMonitor(ksp,i,rnorm);CHKERRQ(ierr);
ierr = (*ksp->converged)(ksp,i,rnorm,&ksp->reason,ksp->cnvP);CHKERRQ(ierr);
//.........这里部分代码省略.........
示例14: KSPPIPEFGMRESCycle
static PetscErrorCode KSPPIPEFGMRESCycle(PetscInt *itcount,KSP ksp)
{
KSP_PIPEFGMRES *pipefgmres = (KSP_PIPEFGMRES*)(ksp->data);
PetscReal res_norm;
PetscReal hapbnd,tt;
PetscScalar *hh,*hes,*lhh,shift = pipefgmres->shift;
PetscBool hapend = PETSC_FALSE; /* indicates happy breakdown ending */
PetscErrorCode ierr;
PetscInt loc_it; /* local count of # of dir. in Krylov space */
PetscInt max_k = pipefgmres->max_k; /* max # of directions Krylov space */
PetscInt i,j,k;
Mat Amat,Pmat;
Vec Q,W; /* Pipelining vectors */
Vec *redux = pipefgmres->redux; /* workspace for single reduction */
PetscFunctionBegin;
if (itcount) *itcount = 0;
/* Assign simpler names to these vectors, allocated as pipelining workspace */
Q = VEC_Q;
W = VEC_W;
/* Allocate memory for orthogonalization work (freed in the GMRES Destroy routine)*/
/* Note that we add an extra value here to allow for a single reduction */
if (!pipefgmres->orthogwork) { ierr = PetscMalloc1(pipefgmres->max_k + 2 ,&pipefgmres->orthogwork);CHKERRQ(ierr);
}
lhh = pipefgmres->orthogwork;
/* Number of pseudo iterations since last restart is the number
of prestart directions */
loc_it = 0;
/* note: (pipefgmres->it) is always set one less than (loc_it) It is used in
KSPBUILDSolution_PIPEFGMRES, where it is passed to KSPPIPEFGMRESBuildSoln.
Note that when KSPPIPEFGMRESBuildSoln is called from this function,
(loc_it -1) is passed, so the two are equivalent */
pipefgmres->it = (loc_it - 1);
/* initial residual is in VEC_VV(0) - compute its norm*/
ierr = VecNorm(VEC_VV(0),NORM_2,&res_norm);CHKERRQ(ierr);
/* first entry in right-hand-side of hessenberg system is just
the initial residual norm */
*RS(0) = res_norm;
ksp->rnorm = res_norm;
ierr = KSPLogResidualHistory(ksp,res_norm);CHKERRQ(ierr);
ierr = KSPMonitor(ksp,ksp->its,res_norm);CHKERRQ(ierr);
/* check for the convergence - maybe the current guess is good enough */
ierr = (*ksp->converged)(ksp,ksp->its,res_norm,&ksp->reason,ksp->cnvP);CHKERRQ(ierr);
if (ksp->reason) {
if (itcount) *itcount = 0;
PetscFunctionReturn(0);
}
/* scale VEC_VV (the initial residual) */
ierr = VecScale(VEC_VV(0),1.0/res_norm);CHKERRQ(ierr);
/* Fill the pipeline */
ierr = KSP_PCApply(ksp,VEC_VV(loc_it),PREVEC(loc_it));CHKERRQ(ierr);
ierr = PCGetOperators(ksp->pc,&Amat,&Pmat);CHKERRQ(ierr);
ierr = KSP_MatMult(ksp,Amat,PREVEC(loc_it),ZVEC(loc_it));CHKERRQ(ierr);
ierr = VecAXPY(ZVEC(loc_it),-shift,VEC_VV(loc_it));CHKERRQ(ierr); /* Note shift */
/* MAIN ITERATION LOOP BEGINNING*/
/* keep iterating until we have converged OR generated the max number
of directions OR reached the max number of iterations for the method */
while (!ksp->reason && loc_it < max_k && ksp->its < ksp->max_it) {
if (loc_it) {
ierr = KSPLogResidualHistory(ksp,res_norm);CHKERRQ(ierr);
ierr = KSPMonitor(ksp,ksp->its,res_norm);CHKERRQ(ierr);
}
pipefgmres->it = (loc_it - 1);
/* see if more space is needed for work vectors */
if (pipefgmres->vv_allocated <= loc_it + VEC_OFFSET + 1) {
ierr = KSPPIPEFGMRESGetNewVectors(ksp,loc_it+1);CHKERRQ(ierr);
/* (loc_it+1) is passed in as number of the first vector that should
be allocated */
}
/* Note that these inner products are with "Z" now, so
in particular, lhh[loc_it] is the 'barred' or 'shifted' value,
not the value from the equivalent FGMRES run (even in exact arithmetic)
That is, the H we need for the Arnoldi relation is different from the
coefficients we use in the orthogonalization process,because of the shift */
/* Do some local twiddling to allow for a single reduction */
for(i=0;i<loc_it+1;i++){
redux[i] = VEC_VV(i);
}
redux[loc_it+1] = ZVEC(loc_it);
/* note the extra dot product which ends up in lh[loc_it+1], which computes ||z||^2 */
ierr = VecMDotBegin(ZVEC(loc_it),loc_it+2,redux,lhh);CHKERRQ(ierr);
/* Start the split reduction (This actually calls the MPI_Iallreduce, otherwise, the reduction is simply delayed until the "end" call)*/
ierr = PetscCommSplitReductionBegin(PetscObjectComm((PetscObject)ZVEC(loc_it)));CHKERRQ(ierr);
//.........这里部分代码省略.........
示例15: KSPFGMRESCycle
PetscErrorCode KSPFGMRESCycle(PetscInt *itcount,KSP ksp)
{
KSP_FGMRES *fgmres = (KSP_FGMRES*)(ksp->data);
PetscReal res_norm;
PetscReal hapbnd,tt;
PetscBool hapend = PETSC_FALSE; /* indicates happy breakdown ending */
PetscErrorCode ierr;
PetscInt loc_it; /* local count of # of dir. in Krylov space */
PetscInt max_k = fgmres->max_k; /* max # of directions Krylov space */
Mat Amat,Pmat;
MatStructure pflag;
PetscFunctionBegin;
/* Number of pseudo iterations since last restart is the number
of prestart directions */
loc_it = 0;
/* note: (fgmres->it) is always set one less than (loc_it) It is used in
KSPBUILDSolution_FGMRES, where it is passed to KSPFGMRESBuildSoln.
Note that when KSPFGMRESBuildSoln is called from this function,
(loc_it -1) is passed, so the two are equivalent */
fgmres->it = (loc_it - 1);
/* initial residual is in VEC_VV(0) - compute its norm*/
ierr = VecNorm(VEC_VV(0),NORM_2,&res_norm);CHKERRQ(ierr);
/* first entry in right-hand-side of hessenberg system is just
the initial residual norm */
*RS(0) = res_norm;
ksp->rnorm = res_norm;
ierr = KSPLogResidualHistory(ksp,res_norm);CHKERRQ(ierr);
ierr = KSPMonitor(ksp,ksp->its,res_norm);CHKERRQ(ierr);
/* check for the convergence - maybe the current guess is good enough */
ierr = (*ksp->converged)(ksp,ksp->its,res_norm,&ksp->reason,ksp->cnvP);CHKERRQ(ierr);
if (ksp->reason) {
if (itcount) *itcount = 0;
PetscFunctionReturn(0);
}
/* scale VEC_VV (the initial residual) */
ierr = VecScale(VEC_VV(0),1.0/res_norm);CHKERRQ(ierr);
/* MAIN ITERATION LOOP BEGINNING*/
/* keep iterating until we have converged OR generated the max number
of directions OR reached the max number of iterations for the method */
while (!ksp->reason && loc_it < max_k && ksp->its < ksp->max_it) {
if (loc_it) {
ierr = KSPLogResidualHistory(ksp,res_norm);CHKERRQ(ierr);
ierr = KSPMonitor(ksp,ksp->its,res_norm);CHKERRQ(ierr);
}
fgmres->it = (loc_it - 1);
/* see if more space is needed for work vectors */
if (fgmres->vv_allocated <= loc_it + VEC_OFFSET + 1) {
ierr = KSPFGMRESGetNewVectors(ksp,loc_it+1);CHKERRQ(ierr);
/* (loc_it+1) is passed in as number of the first vector that should
be allocated */
}
/* CHANGE THE PRECONDITIONER? */
/* ModifyPC is the callback function that can be used to
change the PC or its attributes before its applied */
(*fgmres->modifypc)(ksp,ksp->its,loc_it,res_norm,fgmres->modifyctx);
/* apply PRECONDITIONER to direction vector and store with
preconditioned vectors in prevec */
ierr = KSP_PCApply(ksp,VEC_VV(loc_it),PREVEC(loc_it));CHKERRQ(ierr);
ierr = PCGetOperators(ksp->pc,&Amat,&Pmat,&pflag);CHKERRQ(ierr);
/* Multiply preconditioned vector by operator - put in VEC_VV(loc_it+1) */
ierr = MatMult(Amat,PREVEC(loc_it),VEC_VV(1+loc_it));CHKERRQ(ierr);
/* update hessenberg matrix and do Gram-Schmidt - new direction is in
VEC_VV(1+loc_it)*/
ierr = (*fgmres->orthog)(ksp,loc_it);CHKERRQ(ierr);
/* new entry in hessenburg is the 2-norm of our new direction */
ierr = VecNorm(VEC_VV(loc_it+1),NORM_2,&tt);CHKERRQ(ierr);
*HH(loc_it+1,loc_it) = tt;
*HES(loc_it+1,loc_it) = tt;
/* Happy Breakdown Check */
hapbnd = PetscAbsScalar((tt) / *RS(loc_it));
/* RS(loc_it) contains the res_norm from the last iteration */
hapbnd = PetscMin(fgmres->haptol,hapbnd);
if (tt > hapbnd) {
/* scale new direction by its norm */
ierr = VecScale(VEC_VV(loc_it+1),1.0/tt);CHKERRQ(ierr);
} else {
/* This happens when the solution is exactly reached. */
/* So there is no new direction... */
ierr = VecSet(VEC_TEMP,0.0);CHKERRQ(ierr); /* set VEC_TEMP to 0 */
hapend = PETSC_TRUE;
}
//.........这里部分代码省略.........