本文整理汇总了C++中KSP_MatMult函数的典型用法代码示例。如果您正苦于以下问题:C++ KSP_MatMult函数的具体用法?C++ KSP_MatMult怎么用?C++ KSP_MatMult使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了KSP_MatMult函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: 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);
}
示例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: KSPSolve_GCR
static PetscErrorCode KSPSolve_GCR(KSP ksp)
{
KSP_GCR *ctx = (KSP_GCR*)ksp->data;
PetscErrorCode ierr;
Mat A, B;
Vec r,b,x;
PetscReal norm_r;
PetscFunctionBegin;
ierr = KSPGetOperators(ksp, &A, &B);CHKERRQ(ierr);
x = ksp->vec_sol;
b = ksp->vec_rhs;
r = ctx->R;
/* compute initial residual */
ierr = KSP_MatMult(ksp,A, x, r);CHKERRQ(ierr);
ierr = VecAYPX(r, -1.0, b);CHKERRQ(ierr); /* r = b - A x */
ierr = VecNorm(r, NORM_2, &norm_r);CHKERRQ(ierr);
KSPCheckNorm(ksp,norm_r);
ksp->its = 0;
ksp->rnorm0 = norm_r;
ierr = KSPLogResidualHistory(ksp,ksp->rnorm0);CHKERRQ(ierr);
ierr = KSPMonitor(ksp,ksp->its,ksp->rnorm0);CHKERRQ(ierr);
ierr = (*ksp->converged)(ksp,ksp->its,ksp->rnorm0,&ksp->reason,ksp->cnvP);CHKERRQ(ierr);
if (ksp->reason) PetscFunctionReturn(0);
do {
ierr = KSPSolve_GCR_cycle(ksp);CHKERRQ(ierr);
if (ksp->reason) break; /* catch case when convergence occurs inside the cycle */
} while (ksp->its < ksp->max_it);CHKERRQ(ierr);
if (ksp->its >= ksp->max_it) ksp->reason = KSP_DIVERGED_ITS;
PetscFunctionReturn(0);
}
示例4: KSPFischerGuessUpdate_Method1
PetscErrorCode KSPFischerGuessUpdate_Method1(KSPFischerGuess_Method1 *itg,Vec x)
{
PetscReal norm;
PetscErrorCode ierr;
int curl = itg->curl,i;
PetscFunctionBegin;
PetscValidHeaderSpecific(x,VEC_CLASSID,2);
PetscValidPointer(itg,3);
if (curl == itg->maxl) {
ierr = KSP_MatMult(itg->ksp,itg->mat,x,itg->btilde[0]);CHKERRQ(ierr);
ierr = VecNormalize(itg->btilde[0],&norm);CHKERRQ(ierr);
ierr = VecCopy(x,itg->xtilde[0]);CHKERRQ(ierr);
ierr = VecScale(itg->xtilde[0],1.0/norm);CHKERRQ(ierr);
itg->curl = 1;
} else {
if (!curl) {
ierr = VecCopy(x,itg->xtilde[curl]);CHKERRQ(ierr);
} else {
ierr = VecWAXPY(itg->xtilde[curl],-1.0,itg->guess,x);CHKERRQ(ierr);
}
ierr = KSP_MatMult(itg->ksp,itg->mat,itg->xtilde[curl],itg->btilde[curl]);CHKERRQ(ierr);
ierr = VecMDot(itg->btilde[curl],curl,itg->btilde,itg->alpha);CHKERRQ(ierr);
for (i=0; i<curl; i++) itg->alpha[i] = -itg->alpha[i];
ierr = VecMAXPY(itg->btilde[curl],curl,itg->alpha,itg->btilde);CHKERRQ(ierr);
ierr = VecMAXPY(itg->xtilde[curl],curl,itg->alpha,itg->xtilde);CHKERRQ(ierr);
ierr = VecNormalize(itg->btilde[curl],&norm);CHKERRQ(ierr);
if (norm) {
ierr = VecScale(itg->xtilde[curl],1.0/norm);CHKERRQ(ierr);
itg->curl++;
} else {
ierr = PetscInfo(itg->ksp,"Not increasing dimension of Fischer space because new direction is identical to previous\n");CHKERRQ(ierr);
}
}
PetscFunctionReturn(0);
}
示例5: 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);
}
示例6: KSPSolve_LCD
PetscErrorCode KSPSolve_LCD(KSP ksp)
{
PetscErrorCode ierr;
PetscInt it,j,max_k;
PetscScalar alfa, beta, num, den, mone;
PetscReal rnorm;
Vec X,B,R,Z;
KSP_LCD *lcd;
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);
lcd = (KSP_LCD*)ksp->data;
X = ksp->vec_sol;
B = ksp->vec_rhs;
R = ksp->work[0];
Z = ksp->work[1];
max_k = lcd->restart;
mone = -1;
ierr = PCGetOperators(ksp->pc,&Amat,&Pmat);
CHKERRQ(ierr);
ksp->its = 0;
if (!ksp->guess_zero) {
ierr = KSP_MatMult(ksp,Amat,X,Z);
CHKERRQ(ierr); /* z <- b - Ax */
ierr = VecAYPX(Z,mone,B);
CHKERRQ(ierr);
} else {
ierr = VecCopy(B,Z);
CHKERRQ(ierr); /* z <- b (x is 0) */
}
ierr = KSP_PCApply(ksp,Z,R);
CHKERRQ(ierr); /* r <- M^-1z */
ierr = VecNorm(R,NORM_2,&rnorm);
CHKERRQ(ierr);
ierr = KSPLogResidualHistory(ksp,rnorm);
CHKERRQ(ierr);
ierr = KSPMonitor(ksp,0,rnorm);
CHKERRQ(ierr);
ksp->rnorm = rnorm;
/* test for convergence */
ierr = (*ksp->converged)(ksp,0,rnorm,&ksp->reason,ksp->cnvP);
CHKERRQ(ierr);
if (ksp->reason) PetscFunctionReturn(0);
it = 0;
VecCopy(R,lcd->P[0]);
while (!ksp->reason && ksp->its < ksp->max_it) {
it = 0;
ierr = KSP_MatMult(ksp,Amat,lcd->P[it],Z);
CHKERRQ(ierr);
ierr = KSP_PCApply(ksp,Z,lcd->Q[it]);
CHKERRQ(ierr);
while (!ksp->reason && it < max_k && ksp->its < ksp->max_it) {
ksp->its++;
ierr = VecDot(lcd->P[it],R,&num);
CHKERRQ(ierr);
ierr = VecDot(lcd->P[it],lcd->Q[it], &den);
CHKERRQ(ierr);
alfa = num/den;
ierr = VecAXPY(X,alfa,lcd->P[it]);
CHKERRQ(ierr);
ierr = VecAXPY(R,-alfa,lcd->Q[it]);
CHKERRQ(ierr);
ierr = VecNorm(R,NORM_2,&rnorm);
CHKERRQ(ierr);
ksp->rnorm = rnorm;
ierr = KSPLogResidualHistory(ksp,rnorm);
CHKERRQ(ierr);
ierr = KSPMonitor(ksp,ksp->its,rnorm);
CHKERRQ(ierr);
ierr = (*ksp->converged)(ksp,ksp->its,rnorm,&ksp->reason,ksp->cnvP);
CHKERRQ(ierr);
if (ksp->reason) break;
ierr = VecCopy(R,lcd->P[it+1]);
CHKERRQ(ierr);
ierr = KSP_MatMult(ksp,Amat,lcd->P[it+1],Z);
CHKERRQ(ierr);
ierr = KSP_PCApply(ksp,Z,lcd->Q[it+1]);
CHKERRQ(ierr);
for (j = 0; j <= it; j++) {
ierr = VecDot(lcd->P[j],lcd->Q[it+1],&num);
CHKERRQ(ierr);
ierr = VecDot(lcd->P[j],lcd->Q[j],&den);
CHKERRQ(ierr);
beta = -num/den;
//.........这里部分代码省略.........
示例7: KSPSolve_GROPPCG
PetscErrorCode KSPSolve_GROPPCG(KSP ksp)
{
PetscErrorCode ierr;
PetscInt i;
PetscScalar alpha,beta = 0.0,gamma,gammaNew,t;
PetscReal dp = 0.0;
Vec x,b,r,p,s,S,z,Z;
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);
x = ksp->vec_sol;
b = ksp->vec_rhs;
r = ksp->work[0];
p = ksp->work[1];
s = ksp->work[2];
S = ksp->work[3];
z = ksp->work[4];
Z = ksp->work[5];
ierr = PCGetOperators(ksp->pc,&Amat,&Pmat);CHKERRQ(ierr);
ksp->its = 0;
if (!ksp->guess_zero) {
ierr = KSP_MatMult(ksp,Amat,x,r);CHKERRQ(ierr); /* r <- b - Ax */
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 <- Br */
ierr = VecCopy(z,p);CHKERRQ(ierr); /* p <- z */
ierr = VecDotBegin(r,z,&gamma);CHKERRQ(ierr); /* gamma <- z'*r */
ierr = PetscCommSplitReductionBegin(PetscObjectComm((PetscObject)r));CHKERRQ(ierr);
ierr = KSP_MatMult(ksp,Amat,p,s);CHKERRQ(ierr); /* s <- Ap */
ierr = VecDotEnd(r,z,&gamma);CHKERRQ(ierr); /* gamma <- z'*r */
switch (ksp->normtype) {
case KSP_NORM_PRECONDITIONED:
/* This could be merged with the computation of gamma above */
ierr = VecNorm(z,NORM_2,&dp);CHKERRQ(ierr); /* dp <- z'*z = e'*A'*B'*B*A'*e' */
break;
case KSP_NORM_UNPRECONDITIONED:
/* This could be merged with the computation of gamma above */
ierr = VecNorm(r,NORM_2,&dp);CHKERRQ(ierr); /* dp <- r'*r = e'*A'*A*e */
break;
case KSP_NORM_NATURAL:
if (PetscIsInfOrNanScalar(gamma)) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_FP,"Infinite or not-a-number generated in dot product");
dp = PetscSqrtReal(PetscAbsScalar(gamma)); /* dp <- r'*z = r'*B*r = e'*A'*B*A*e */
break;
case KSP_NORM_NONE:
dp = 0.0;
break;
default: SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"%s",KSPNormTypes[ksp->normtype]);
}
ierr = KSPLogResidualHistory(ksp,dp);CHKERRQ(ierr);
ierr = KSPMonitor(ksp,0,dp);CHKERRQ(ierr);
ksp->rnorm = dp;
ierr = (*ksp->converged)(ksp,0,dp,&ksp->reason,ksp->cnvP);CHKERRQ(ierr); /* test for convergence */
if (ksp->reason) PetscFunctionReturn(0);
i = 0;
do {
ksp->its = i+1;
i++;
ierr = VecDotBegin(p,s,&t);CHKERRQ(ierr);
ierr = PetscCommSplitReductionBegin(PetscObjectComm((PetscObject)p));CHKERRQ(ierr);
ierr = KSP_PCApply(ksp,s,S);CHKERRQ(ierr); /* S <- Bs */
ierr = VecDotEnd(p,s,&t);CHKERRQ(ierr);
alpha = gamma / t;
ierr = VecAXPY(x, alpha,p);CHKERRQ(ierr); /* x <- x + alpha * p */
ierr = VecAXPY(r,-alpha,s);CHKERRQ(ierr); /* r <- r - alpha * s */
ierr = VecAXPY(z,-alpha,S);CHKERRQ(ierr); /* z <- z - alpha * S */
if (ksp->normtype == KSP_NORM_UNPRECONDITIONED) {
ierr = VecNormBegin(r,NORM_2,&dp);CHKERRQ(ierr);
} else if (ksp->normtype == KSP_NORM_PRECONDITIONED) {
ierr = VecNormBegin(z,NORM_2,&dp);CHKERRQ(ierr);
}
ierr = VecDotBegin(r,z,&gammaNew);CHKERRQ(ierr);
ierr = PetscCommSplitReductionBegin(PetscObjectComm((PetscObject)r));CHKERRQ(ierr);
ierr = KSP_MatMult(ksp,Amat,z,Z);CHKERRQ(ierr); /* Z <- Az */
if (ksp->normtype == KSP_NORM_UNPRECONDITIONED) {
ierr = VecNormEnd(r,NORM_2,&dp);CHKERRQ(ierr);
} else if (ksp->normtype == KSP_NORM_PRECONDITIONED) {
ierr = VecNormEnd(z,NORM_2,&dp);CHKERRQ(ierr);
}
ierr = VecDotEnd(r,z,&gammaNew);CHKERRQ(ierr);
if (ksp->normtype == KSP_NORM_NATURAL) {
if (PetscIsInfOrNanScalar(gammaNew)) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_FP,"Infinite or not-a-number generated in dot product");
//.........这里部分代码省略.........
示例8: KSPSolve_GCR_cycle
static PetscErrorCode KSPSolve_GCR_cycle(KSP ksp)
{
KSP_GCR *ctx = (KSP_GCR*)ksp->data;
PetscErrorCode ierr;
PetscScalar r_dot_v;
Mat A, B;
PC pc;
Vec s,v,r;
/*
The residual norm will not be computed when ksp->its > ksp->chknorm hence need to initialize norm_r with some dummy value
*/
PetscReal norm_r = 0.0,nrm;
PetscInt k, i, restart;
Vec x;
PetscFunctionBegin;
restart = ctx->restart;
ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr);
ierr = KSPGetOperators(ksp, &A, &B);CHKERRQ(ierr);
x = ksp->vec_sol;
r = ctx->R;
for (k=0; k<restart; k++) {
v = ctx->VV[k];
s = ctx->SS[k];
if (ctx->modifypc) {
ierr = (*ctx->modifypc)(ksp,ksp->its,ksp->rnorm,ctx->modifypc_ctx);CHKERRQ(ierr);
}
ierr = KSP_PCApply(ksp, r, s);CHKERRQ(ierr); /* s = B^{-1} r */
ierr = KSP_MatMult(ksp,A, s, v);CHKERRQ(ierr); /* v = A s */
ierr = VecMDot(v,k, ctx->VV, ctx->val);CHKERRQ(ierr);
for (i=0; i<k; i++) ctx->val[i] = -ctx->val[i];
ierr = VecMAXPY(v,k,ctx->val,ctx->VV);CHKERRQ(ierr); /* v = v - sum_{i=0}^{k-1} alpha_i v_i */
ierr = VecMAXPY(s,k,ctx->val,ctx->SS);CHKERRQ(ierr); /* s = s - sum_{i=0}^{k-1} alpha_i s_i */
ierr = VecDotNorm2(r,v,&r_dot_v,&nrm);CHKERRQ(ierr);
nrm = PetscSqrtReal(nrm);
r_dot_v = r_dot_v/nrm;
ierr = VecScale(v, 1.0/nrm);CHKERRQ(ierr);
ierr = VecScale(s, 1.0/nrm);CHKERRQ(ierr);
ierr = VecAXPY(x, r_dot_v, s);CHKERRQ(ierr);
ierr = VecAXPY(r, -r_dot_v, v);CHKERRQ(ierr);
if (ksp->its > ksp->chknorm) {
ierr = VecNorm(r, NORM_2, &norm_r);CHKERRQ(ierr);
KSPCheckNorm(ksp,norm_r);
}
/* update the local counter and the global counter */
ksp->its++;
ksp->rnorm = norm_r;
ierr = KSPLogResidualHistory(ksp,norm_r);CHKERRQ(ierr);
ierr = KSPMonitor(ksp,ksp->its,norm_r);CHKERRQ(ierr);
if (ksp->its-1 > ksp->chknorm) {
ierr = (*ksp->converged)(ksp,ksp->its,norm_r,&ksp->reason,ksp->cnvP);CHKERRQ(ierr);
if (ksp->reason) break;
}
if (ksp->its >= ksp->max_it) {
ksp->reason = KSP_CONVERGED_ITS;
break;
}
}
ctx->n_restarts++;
PetscFunctionReturn(0);
}
示例9: MyKSPFGMRESCycle
PetscErrorCode MyKSPFGMRESCycle(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;
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 = MyKSPFGMRESGetNewVectors(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);CHKERRQ(ierr);
/* Multiply preconditioned vector by operator - put in VEC_VV(loc_it+1) */
ierr = KSP_MatMult(ksp,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;
}
/* note that for FGMRES we could get HES(loc_it+1, loc_it) = 0 and the
//.........这里部分代码省略.........
示例10: KSPSolve_STCG
//.........这里部分代码省略.........
/***************************************************************************/
/* Check the preconditioner for numerical problems and for positive */
/* definiteness. The check for not-a-number and infinite values need be */
/* performed only once. */
/***************************************************************************/
ierr = KSP_PCApply(ksp, r, z);CHKERRQ(ierr); /* z = inv(M) r */
ierr = VecDot(r, z, &rz);CHKERRQ(ierr); /* rz = r^T inv(M) r */
if (PetscIsInfOrNanScalar(rz)) {
/*************************************************************************/
/* The preconditioner contains not-a-number or an infinite value. */
/* Return the gradient direction intersected with the trust region. */
/*************************************************************************/
ksp->reason = KSP_DIVERGED_NANORINF;
ierr = PetscInfo1(ksp, "KSPSolve_STCG: bad preconditioner: rz=%g\n", rz);CHKERRQ(ierr);
if (cg->radius != 0) {
if (r2 >= rr) {
alpha = 1.0;
cg->norm_d = PetscSqrtReal(rr);
} else {
alpha = PetscSqrtReal(r2 / rr);
cg->norm_d = cg->radius;
}
ierr = VecAXPY(d, alpha, r);CHKERRQ(ierr); /* d = d + alpha r */
/***********************************************************************/
/* Compute objective function. */
/***********************************************************************/
ierr = KSP_MatMult(ksp, Qmat, d, z);CHKERRQ(ierr);
ierr = VecAYPX(z, -0.5, ksp->vec_rhs);CHKERRQ(ierr);
ierr = VecDot(d, z, &cg->o_fcn);CHKERRQ(ierr);
cg->o_fcn = -cg->o_fcn;
++ksp->its;
}
PetscFunctionReturn(0);
}
if (rz < 0.0) {
/*************************************************************************/
/* The preconditioner is indefinite. Because this is the first */
/* and we do not have a direction yet, we use the gradient step. Note */
/* that we cannot use the preconditioned norm when computing the step */
/* because the matrix is indefinite. */
/*************************************************************************/
ksp->reason = KSP_DIVERGED_INDEFINITE_PC;
ierr = PetscInfo1(ksp, "KSPSolve_STCG: indefinite preconditioner: rz=%g\n", rz);CHKERRQ(ierr);
if (cg->radius != 0.0) {
if (r2 >= rr) {
alpha = 1.0;
cg->norm_d = PetscSqrtReal(rr);
} else {
alpha = PetscSqrtReal(r2 / rr);
cg->norm_d = cg->radius;
}
ierr = VecAXPY(d, alpha, r);CHKERRQ(ierr); /* d = d + alpha r */
/***********************************************************************/
/* Compute objective function. */
示例11: KSPSolve_FBCGSR
static PetscErrorCode KSPSolve_FBCGSR(KSP ksp)
{
PetscErrorCode ierr;
PetscInt i,j,N;
PetscScalar tau,sigma,alpha,omega,beta;
PetscReal rho;
PetscScalar xi1,xi2,xi3,xi4;
Vec X,B,P,P2,RP,R,V,S,T,S2;
PetscScalar *PETSC_RESTRICT rp, *PETSC_RESTRICT r, *PETSC_RESTRICT p;
PetscScalar *PETSC_RESTRICT v, *PETSC_RESTRICT s, *PETSC_RESTRICT t, *PETSC_RESTRICT s2;
PetscScalar insums[4],outsums[4];
KSP_BCGS *bcgs = (KSP_BCGS*)ksp->data;
PC pc;
Mat mat;
PetscFunctionBegin;
if (!ksp->vec_rhs->petscnative) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Only coded for PETSc vectors");
ierr = VecGetLocalSize(ksp->vec_sol,&N);CHKERRQ(ierr);
X = ksp->vec_sol;
B = ksp->vec_rhs;
P2 = ksp->work[0];
/* The followings are involved in modified inner product calculations and vector updates */
RP = ksp->work[1]; ierr = VecGetArray(RP,(PetscScalar**)&rp);CHKERRQ(ierr); ierr = VecRestoreArray(RP,NULL);CHKERRQ(ierr);
R = ksp->work[2]; ierr = VecGetArray(R,(PetscScalar**)&r);CHKERRQ(ierr); ierr = VecRestoreArray(R,NULL);CHKERRQ(ierr);
P = ksp->work[3]; ierr = VecGetArray(P,(PetscScalar**)&p);CHKERRQ(ierr); ierr = VecRestoreArray(P,NULL);CHKERRQ(ierr);
V = ksp->work[4]; ierr = VecGetArray(V,(PetscScalar**)&v);CHKERRQ(ierr); ierr = VecRestoreArray(V,NULL);CHKERRQ(ierr);
S = ksp->work[5]; ierr = VecGetArray(S,(PetscScalar**)&s);CHKERRQ(ierr); ierr = VecRestoreArray(S,NULL);CHKERRQ(ierr);
T = ksp->work[6]; ierr = VecGetArray(T,(PetscScalar**)&t);CHKERRQ(ierr); ierr = VecRestoreArray(T,NULL);CHKERRQ(ierr);
S2 = ksp->work[7]; ierr = VecGetArray(S2,(PetscScalar**)&s2);CHKERRQ(ierr); ierr = VecRestoreArray(S2,NULL);CHKERRQ(ierr);
/* Only supports right preconditioning */
if (ksp->pc_side != PC_RIGHT) SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"KSP fbcgsr does not support %s",PCSides[ksp->pc_side]);
if (!ksp->guess_zero) {
if (!bcgs->guess) {
ierr = VecDuplicate(X,&bcgs->guess);CHKERRQ(ierr);
}
ierr = VecCopy(X,bcgs->guess);CHKERRQ(ierr);
} else {
ierr = VecSet(X,0.0);CHKERRQ(ierr);
}
/* Compute initial residual */
ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
ierr = PCSetUp(pc);CHKERRQ(ierr);
ierr = PCGetOperators(pc,&mat,NULL);CHKERRQ(ierr);
if (!ksp->guess_zero) {
ierr = KSP_MatMult(ksp,mat,X,P2);CHKERRQ(ierr); /* P2 is used as temporary storage */
ierr = VecCopy(B,R);CHKERRQ(ierr);
ierr = VecAXPY(R,-1.0,P2);CHKERRQ(ierr);
} else {
ierr = VecCopy(B,R);CHKERRQ(ierr);
}
/* Test for nothing to do */
ierr = VecNorm(R,NORM_2,&rho);CHKERRQ(ierr);
ierr = PetscObjectSAWsTakeAccess((PetscObject)ksp);CHKERRQ(ierr);
ksp->its = 0;
ksp->rnorm = rho;
ierr = PetscObjectSAWsGrantAccess((PetscObject)ksp);CHKERRQ(ierr);
ierr = KSPLogResidualHistory(ksp,rho);CHKERRQ(ierr);
ierr = KSPMonitor(ksp,0,rho);CHKERRQ(ierr);
ierr = (*ksp->converged)(ksp,0,rho,&ksp->reason,ksp->cnvP);CHKERRQ(ierr);
if (ksp->reason) PetscFunctionReturn(0);
/* Initialize iterates */
ierr = VecCopy(R,RP);CHKERRQ(ierr); /* rp <- r */
ierr = VecCopy(R,P);CHKERRQ(ierr); /* p <- r */
/* Big loop */
for (i=0; i<ksp->max_it; i++) {
/* matmult and pc */
ierr = KSP_PCApply(ksp,P,P2);CHKERRQ(ierr); /* p2 <- K p */
ierr = KSP_MatMult(ksp,mat,P2,V);CHKERRQ(ierr); /* v <- A p2 */
/* inner prodcuts */
if (i==0) {
tau = rho*rho;
ierr = VecDot(V,RP,&sigma);CHKERRQ(ierr); /* sigma <- (v,rp) */
} else {
ierr = PetscLogEventBegin(VEC_ReduceArithmetic,0,0,0,0);CHKERRQ(ierr);
tau = sigma = 0.0;
for (j=0; j<N; j++) {
tau += r[j]*rp[j]; /* tau <- (r,rp) */
sigma += v[j]*rp[j]; /* sigma <- (v,rp) */
}
ierr = PetscLogFlops(4.0*N);CHKERRQ(ierr);
ierr = PetscLogEventEnd(VEC_ReduceArithmetic,0,0,0,0);CHKERRQ(ierr);
insums[0] = tau;
insums[1] = sigma;
ierr = PetscLogEventBegin(VEC_ReduceCommunication,0,0,0,0);CHKERRQ(ierr);
ierr = MPIU_Allreduce(insums,outsums,2,MPIU_SCALAR,MPIU_SUM,PetscObjectComm((PetscObject)ksp));CHKERRQ(ierr);
ierr = PetscLogEventEnd(VEC_ReduceCommunication,0,0,0,0);CHKERRQ(ierr);
tau = outsums[0];
sigma = outsums[1];
}
/* scalar update */
//.........这里部分代码省略.........
示例12: KSPSolve_PIPECG
PetscErrorCode KSPSolve_PIPECG(KSP ksp)
{
PetscErrorCode ierr;
PetscInt i;
PetscScalar alpha = 0.0,beta = 0.0,gamma = 0.0,gammaold = 0.0,delta = 0.0;
PetscReal dp = 0.0;
Vec X,B,Z,P,W,Q,U,M,N,R,S;
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);
X = ksp->vec_sol;
B = ksp->vec_rhs;
M = ksp->work[0];
Z = ksp->work[1];
P = ksp->work[2];
N = ksp->work[3];
W = ksp->work[4];
Q = ksp->work[5];
U = ksp->work[6];
R = ksp->work[7];
S = ksp->work[8];
ierr = PCGetOperators(ksp->pc,&Amat,&Pmat);CHKERRQ(ierr);
ksp->its = 0;
if (!ksp->guess_zero) {
ierr = KSP_MatMult(ksp,Amat,X,R);CHKERRQ(ierr); /* r <- b - Ax */
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,U);CHKERRQ(ierr); /* u <- Br */
switch (ksp->normtype) {
case KSP_NORM_PRECONDITIONED:
ierr = VecNormBegin(U,NORM_2,&dp);CHKERRQ(ierr); /* dp <- u'*u = e'*A'*B'*B*A'*e' */
ierr = PetscCommSplitReductionBegin(PetscObjectComm((PetscObject)U));CHKERRQ(ierr);
ierr = KSP_MatMult(ksp,Amat,U,W);CHKERRQ(ierr); /* w <- Au */
ierr = VecNormEnd(U,NORM_2,&dp);CHKERRQ(ierr);
break;
case KSP_NORM_UNPRECONDITIONED:
ierr = VecNormBegin(R,NORM_2,&dp);CHKERRQ(ierr); /* dp <- r'*r = e'*A'*A*e */
ierr = PetscCommSplitReductionBegin(PetscObjectComm((PetscObject)R));CHKERRQ(ierr);
ierr = KSP_MatMult(ksp,Amat,U,W);CHKERRQ(ierr); /* w <- Au */
ierr = VecNormEnd(R,NORM_2,&dp);CHKERRQ(ierr);
break;
case KSP_NORM_NATURAL:
ierr = VecDotBegin(R,U,&gamma);CHKERRQ(ierr); /* gamma <- u'*r */
ierr = PetscCommSplitReductionBegin(PetscObjectComm((PetscObject)R));CHKERRQ(ierr);
ierr = KSP_MatMult(ksp,Amat,U,W);CHKERRQ(ierr); /* w <- Au */
ierr = VecDotEnd(R,U,&gamma);CHKERRQ(ierr);
KSPCheckDot(ksp,gamma);
dp = PetscSqrtReal(PetscAbsScalar(gamma)); /* dp <- r'*u = r'*B*r = e'*A'*B*A*e */
break;
case KSP_NORM_NONE:
ierr = KSP_MatMult(ksp,Amat,U,W);CHKERRQ(ierr);
dp = 0.0;
break;
default: SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"%s",KSPNormTypes[ksp->normtype]);
}
ierr = KSPLogResidualHistory(ksp,dp);CHKERRQ(ierr);
ierr = KSPMonitor(ksp,0,dp);CHKERRQ(ierr);
ksp->rnorm = dp;
ierr = (*ksp->converged)(ksp,0,dp,&ksp->reason,ksp->cnvP);CHKERRQ(ierr); /* test for convergence */
if (ksp->reason) PetscFunctionReturn(0);
i = 0;
do {
if (i > 0 && ksp->normtype == KSP_NORM_UNPRECONDITIONED) {
ierr = VecNormBegin(R,NORM_2,&dp);CHKERRQ(ierr);
} else if (i > 0 && ksp->normtype == KSP_NORM_PRECONDITIONED) {
ierr = VecNormBegin(U,NORM_2,&dp);CHKERRQ(ierr);
}
if (!(i == 0 && ksp->normtype == KSP_NORM_NATURAL)) {
ierr = VecDotBegin(R,U,&gamma);CHKERRQ(ierr);
}
ierr = VecDotBegin(W,U,&delta);CHKERRQ(ierr);
ierr = PetscCommSplitReductionBegin(PetscObjectComm((PetscObject)R));CHKERRQ(ierr);
ierr = KSP_PCApply(ksp,W,M);CHKERRQ(ierr); /* m <- Bw */
ierr = KSP_MatMult(ksp,Amat,M,N);CHKERRQ(ierr); /* n <- Am */
if (i > 0 && ksp->normtype == KSP_NORM_UNPRECONDITIONED) {
ierr = VecNormEnd(R,NORM_2,&dp);CHKERRQ(ierr);
} else if (i > 0 && ksp->normtype == KSP_NORM_PRECONDITIONED) {
ierr = VecNormEnd(U,NORM_2,&dp);CHKERRQ(ierr);
}
if (!(i == 0 && ksp->normtype == KSP_NORM_NATURAL)) {
ierr = VecDotEnd(R,U,&gamma);CHKERRQ(ierr);
}
ierr = VecDotEnd(W,U,&delta);CHKERRQ(ierr);
if (i > 0) {
if (ksp->normtype == KSP_NORM_NATURAL) dp = PetscSqrtReal(PetscAbsScalar(gamma));
else if (ksp->normtype == KSP_NORM_NONE) dp = 0.0;
//.........这里部分代码省略.........
示例13: KSPSolve_QCG
PetscErrorCode KSPSolve_QCG(KSP ksp)
{
/*
Correpondence with documentation above:
B = g = gradient,
X = s = step
Note: This is not coded correctly for complex arithmetic!
*/
KSP_QCG *pcgP = (KSP_QCG*)ksp->data;
Mat Amat,Pmat;
Vec W,WA,WA2,R,P,ASP,BS,X,B;
PetscScalar scal,beta,rntrn,step;
PetscReal q1,q2,xnorm,step1,step2,rnrm,btx,xtax;
PetscReal ptasp,rtr,wtasp,bstp;
PetscReal dzero = 0.0,bsnrm;
PetscErrorCode ierr;
PetscInt i,maxit;
PC pc = ksp->pc;
PCSide side;
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 (ksp->transpose_solve) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_SUP,"Currently does not support transpose solve");
ksp->its = 0;
maxit = ksp->max_it;
WA = ksp->work[0];
R = ksp->work[1];
P = ksp->work[2];
ASP = ksp->work[3];
BS = ksp->work[4];
W = ksp->work[5];
WA2 = ksp->work[6];
X = ksp->vec_sol;
B = ksp->vec_rhs;
if (pcgP->delta <= dzero) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_OUTOFRANGE,"Input error: delta <= 0");
ierr = KSPGetPCSide(ksp,&side);CHKERRQ(ierr);
if (side != PC_SYMMETRIC) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_OUTOFRANGE,"Requires symmetric preconditioner!");
/* Initialize variables */
ierr = VecSet(W,0.0);CHKERRQ(ierr); /* W = 0 */
ierr = VecSet(X,0.0);CHKERRQ(ierr); /* X = 0 */
ierr = PCGetOperators(pc,&Amat,&Pmat);CHKERRQ(ierr);
/* Compute: BS = D^{-1} B */
ierr = PCApplySymmetricLeft(pc,B,BS);CHKERRQ(ierr);
ierr = VecNorm(BS,NORM_2,&bsnrm);CHKERRQ(ierr);
ierr = PetscObjectSAWsTakeAccess((PetscObject)ksp);CHKERRQ(ierr);
ksp->its = 0;
ksp->rnorm = bsnrm;
ierr = PetscObjectSAWsGrantAccess((PetscObject)ksp);CHKERRQ(ierr);
ierr = KSPLogResidualHistory(ksp,bsnrm);CHKERRQ(ierr);
ierr = KSPMonitor(ksp,0,bsnrm);CHKERRQ(ierr);
ierr = (*ksp->converged)(ksp,0,bsnrm,&ksp->reason,ksp->cnvP);CHKERRQ(ierr);
if (ksp->reason) PetscFunctionReturn(0);
/* Compute the initial scaled direction and scaled residual */
ierr = VecCopy(BS,R);CHKERRQ(ierr);
ierr = VecScale(R,-1.0);CHKERRQ(ierr);
ierr = VecCopy(R,P);CHKERRQ(ierr);
ierr = VecDotRealPart(R,R,&rtr);CHKERRQ(ierr);
for (i=0; i<=maxit; i++) {
ierr = PetscObjectSAWsTakeAccess((PetscObject)ksp);CHKERRQ(ierr);
ksp->its++;
ierr = PetscObjectSAWsGrantAccess((PetscObject)ksp);CHKERRQ(ierr);
/* Compute: asp = D^{-T}*A*D^{-1}*p */
ierr = PCApplySymmetricRight(pc,P,WA);CHKERRQ(ierr);
ierr = KSP_MatMult(ksp,Amat,WA,WA2);CHKERRQ(ierr);
ierr = PCApplySymmetricLeft(pc,WA2,ASP);CHKERRQ(ierr);
/* Check for negative curvature */
ierr = VecDotRealPart(P,ASP,&ptasp);CHKERRQ(ierr);
if (ptasp <= dzero) {
/* Scaled negative curvature direction: Compute a step so that
||w + step*p|| = delta and QS(w + step*p) is least */
if (!i) {
ierr = VecCopy(P,X);CHKERRQ(ierr);
ierr = VecNorm(X,NORM_2,&xnorm);CHKERRQ(ierr);
scal = pcgP->delta / xnorm;
ierr = VecScale(X,scal);CHKERRQ(ierr);
} else {
/* Compute roots of quadratic */
ierr = KSPQCGQuadraticRoots(W,P,pcgP->delta,&step1,&step2);CHKERRQ(ierr);
ierr = VecDotRealPart(W,ASP,&wtasp);CHKERRQ(ierr);
ierr = VecDotRealPart(BS,P,&bstp);CHKERRQ(ierr);
ierr = VecCopy(W,X);CHKERRQ(ierr);
q1 = step1*(bstp + wtasp + .5*step1*ptasp);
q2 = step2*(bstp + wtasp + .5*step2*ptasp);
if (q1 <= q2) {
ierr = VecAXPY(X,step1,P);CHKERRQ(ierr);
} else {
//.........这里部分代码省略.........
示例14: 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;
//.........这里部分代码省略.........
示例15: KSPSolve_TSIRM
PetscErrorCode KSPSolve_TSIRM(KSP ksp)
{
PetscErrorCode ierr;
KSP_TSIRM *tsirm = (KSP_TSIRM*)ksp->data;
KSP sub_ksp;
PC pc;
Mat AS;
Vec x,b;
PetscScalar *array;
PetscReal norm = 20;
PetscInt i,*ind_row,first_iteration = 1,its = 0,total = 0,col = 0;
PetscInt restart = 30;
KSP ksp_min; /* KSP for minimization */
PC pc_min; /* PC for minimization */
PetscFunctionBegin;
x = ksp->vec_sol; /* Solution vector */
b = ksp->vec_rhs; /* Right-hand side vector */
/* Row indexes (these indexes are global) */
ierr = PetscMalloc1(tsirm->Iend-tsirm->Istart,&ind_row);
CHKERRQ(ierr);
for (i=0; i<tsirm->Iend-tsirm->Istart; i++) ind_row[i] = i+tsirm->Istart;
/* Inner solver */
ierr = KSPGetPC(ksp,&pc);
CHKERRQ(ierr);
ierr = PCKSPGetKSP(pc,&sub_ksp);
CHKERRQ(ierr);
ierr = KSPSetTolerances(sub_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,restart);
CHKERRQ(ierr);
/* previously it seemed good but with SNES it seems not good... */
ierr = KSP_MatMult(sub_ksp,tsirm->A,x,tsirm->r);
CHKERRQ(ierr);
ierr = VecAXPY(tsirm->r,-1,b);
CHKERRQ(ierr);
ierr = VecNorm(tsirm->r,NORM_2,&norm);
CHKERRQ(ierr);
ksp->its = 0;
ierr = KSPConvergedDefault(ksp,ksp->its,norm,&ksp->reason,ksp->cnvP);
CHKERRQ(ierr);
ierr = KSPSetInitialGuessNonzero(sub_ksp,PETSC_TRUE);
CHKERRQ(ierr);
do {
for (col=0; col<tsirm->size_ls && ksp->reason==0; col++) {
/* Solve (inner iteration) */
ierr = KSPSolve(sub_ksp,b,x);
CHKERRQ(ierr);
ierr = KSPGetIterationNumber(sub_ksp,&its);
CHKERRQ(ierr);
total += its;
/* Build S^T */
ierr = VecGetArray(x,&array);
CHKERRQ(ierr);
ierr = MatSetValues(tsirm->S,tsirm->Iend-tsirm->Istart,ind_row,1,&col,array,INSERT_VALUES);
CHKERRQ(ierr);
ierr = VecRestoreArray(x,&array);
CHKERRQ(ierr);
ierr = KSPGetResidualNorm(sub_ksp,&norm);
CHKERRQ(ierr);
ksp->rnorm = norm;
ksp->its ++;
ierr = KSPConvergedDefault(ksp,ksp->its,norm,&ksp->reason,ksp->cnvP);
CHKERRQ(ierr);
ierr = KSPMonitor(ksp,ksp->its,norm);
CHKERRQ(ierr);
}
/* Minimization step */
if (!ksp->reason) {
ierr = MatAssemblyBegin(tsirm->S,MAT_FINAL_ASSEMBLY);
CHKERRQ(ierr);
ierr = MatAssemblyEnd(tsirm->S,MAT_FINAL_ASSEMBLY);
CHKERRQ(ierr);
if (first_iteration) {
ierr = MatMatMult(tsirm->A,tsirm->S,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&AS);
CHKERRQ(ierr);
first_iteration = 0;
} else {
ierr = MatMatMult(tsirm->A,tsirm->S,MAT_REUSE_MATRIX,PETSC_DEFAULT,&AS);
CHKERRQ(ierr);
}
/* CGLS or LSQR method to minimize the residuals*/
ierr = KSPCreate(PETSC_COMM_WORLD,&ksp_min);
CHKERRQ(ierr);
if (tsirm->cgls) {
ierr = KSPSetType(ksp_min,KSPCGLS);
CHKERRQ(ierr);
} else {
ierr = KSPSetType(ksp_min,KSPLSQR);
CHKERRQ(ierr);
}
ierr = KSPSetOperators(ksp_min,AS,AS);
CHKERRQ(ierr);
ierr = KSPSetTolerances(ksp_min,tsirm->tol_ls,PETSC_DEFAULT,PETSC_DEFAULT,tsirm->maxiter_ls);
//.........这里部分代码省略.........