static PetscErrorCode VecConjugate_Nest(Vec x) { Vec_Nest *bx = (Vec_Nest*)x->data; PetscInt j,nr; PetscErrorCode ierr; PetscFunctionBegin; nr = bx->nb; for (j=0; j<nr; j++) { ierr = VecConjugate(bx->v[j]);CHKERRQ(ierr); } PetscFunctionReturn(0); }
void PETSC_STDCALL vecconjugate_(Vec x, int *__ierr ){ *__ierr = VecConjugate( (Vec)PetscToPointer((x) )); }
PetscErrorCode KSPSolve_BiCG(KSP ksp) { PetscErrorCode ierr; PetscInt i; PetscBool diagonalscale; PetscScalar dpi,a=1.0,beta,betaold=1.0,b,ma; PetscReal dp; Vec X,B,Zl,Zr,Rl,Rr,Pl,Pr; Mat Amat,Pmat; 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; Rl = ksp->work[0]; Zl = ksp->work[1]; Pl = ksp->work[2]; Rr = ksp->work[3]; Zr = ksp->work[4]; Pr = ksp->work[5]; ierr = PCGetOperators(ksp->pc,&Amat,&Pmat);CHKERRQ(ierr); if (!ksp->guess_zero) { ierr = KSP_MatMult(ksp,Amat,X,Rr);CHKERRQ(ierr); /* r <- b - Ax */ ierr = VecAYPX(Rr,-1.0,B);CHKERRQ(ierr); } else { ierr = VecCopy(B,Rr);CHKERRQ(ierr); /* r <- b (x is 0) */ } ierr = VecCopy(Rr,Rl);CHKERRQ(ierr); ierr = KSP_PCApply(ksp,Rr,Zr);CHKERRQ(ierr); /* z <- Br */ ierr = VecConjugate(Rl);CHKERRQ(ierr); ierr = KSP_PCApplyTranspose(ksp,Rl,Zl);CHKERRQ(ierr); ierr = VecConjugate(Rl);CHKERRQ(ierr); ierr = VecConjugate(Zl);CHKERRQ(ierr); if (ksp->normtype == KSP_NORM_PRECONDITIONED) { ierr = VecNorm(Zr,NORM_2,&dp);CHKERRQ(ierr); /* dp <- z'*z */ } else { ierr = VecNorm(Rr,NORM_2,&dp);CHKERRQ(ierr); /* dp <- r'*r */ } ierr = KSPMonitor(ksp,0,dp);CHKERRQ(ierr); ierr = PetscObjectSAWsTakeAccess((PetscObject)ksp);CHKERRQ(ierr); ksp->its = 0; ksp->rnorm = dp; ierr = PetscObjectSAWsGrantAccess((PetscObject)ksp);CHKERRQ(ierr); ierr = KSPLogResidualHistory(ksp,dp);CHKERRQ(ierr); ierr = (*ksp->converged)(ksp,0,dp,&ksp->reason,ksp->cnvP);CHKERRQ(ierr); if (ksp->reason) PetscFunctionReturn(0); i = 0; do { ierr = VecDot(Zr,Rl,&beta);CHKERRQ(ierr); /* beta <- r'z */ if (!i) { if (beta == 0.0) { ksp->reason = KSP_DIVERGED_BREAKDOWN_BICG; PetscFunctionReturn(0); } ierr = VecCopy(Zr,Pr);CHKERRQ(ierr); /* p <- z */ ierr = VecCopy(Zl,Pl);CHKERRQ(ierr); } else { b = beta/betaold; ierr = VecAYPX(Pr,b,Zr);CHKERRQ(ierr); /* p <- z + b* p */ b = PetscConj(b); ierr = VecAYPX(Pl,b,Zl);CHKERRQ(ierr); } betaold = beta; ierr = KSP_MatMult(ksp,Amat,Pr,Zr);CHKERRQ(ierr); /* z <- Kp */ ierr = VecConjugate(Pl);CHKERRQ(ierr); ierr = KSP_MatMultTranspose(ksp,Amat,Pl,Zl);CHKERRQ(ierr); ierr = VecConjugate(Pl);CHKERRQ(ierr); ierr = VecConjugate(Zl);CHKERRQ(ierr); ierr = VecDot(Zr,Pl,&dpi);CHKERRQ(ierr); /* dpi <- z'p */ a = beta/dpi; /* a = beta/p'z */ ierr = VecAXPY(X,a,Pr);CHKERRQ(ierr); /* x <- x + ap */ ma = -a; ierr = VecAXPY(Rr,ma,Zr);CHKERRQ(ierr); ma = PetscConj(ma); ierr = VecAXPY(Rl,ma,Zl);CHKERRQ(ierr); if (ksp->normtype == KSP_NORM_PRECONDITIONED) { ierr = KSP_PCApply(ksp,Rr,Zr);CHKERRQ(ierr); /* z <- Br */ ierr = VecConjugate(Rl);CHKERRQ(ierr); ierr = KSP_PCApplyTranspose(ksp,Rl,Zl);CHKERRQ(ierr); ierr = VecConjugate(Rl);CHKERRQ(ierr); ierr = VecConjugate(Zl);CHKERRQ(ierr); ierr = VecNorm(Zr,NORM_2,&dp);CHKERRQ(ierr); /* dp <- z'*z */ } else { ierr = VecNorm(Rr,NORM_2,&dp);CHKERRQ(ierr); /* dp <- r'*r */ } ierr = PetscObjectSAWsTakeAccess((PetscObject)ksp);CHKERRQ(ierr); ksp->its = i+1; ksp->rnorm = dp; ierr = PetscObjectSAWsGrantAccess((PetscObject)ksp);CHKERRQ(ierr); ierr = KSPLogResidualHistory(ksp,dp);CHKERRQ(ierr); ierr = KSPMonitor(ksp,i+1,dp);CHKERRQ(ierr); ierr = (*ksp->converged)(ksp,i+1,dp,&ksp->reason,ksp->cnvP);CHKERRQ(ierr); if (ksp->reason) break; if (ksp->normtype == KSP_NORM_UNPRECONDITIONED) { ierr = KSP_PCApply(ksp,Rr,Zr);CHKERRQ(ierr); /* z <- Br */ ierr = VecConjugate(Rl);CHKERRQ(ierr); ierr = KSP_PCApplyTranspose(ksp,Rl,Zl);CHKERRQ(ierr); ierr = VecConjugate(Rl);CHKERRQ(ierr); ierr = VecConjugate(Zl);CHKERRQ(ierr); } i++; } while (i<ksp->max_it); if (i >= ksp->max_it) ksp->reason = KSP_DIVERGED_ITS; PetscFunctionReturn(0); }