Actual source code: itres.c
1: /*$Id: itres.c,v 1.54 2001/08/07 03:03:45 balay Exp $*/
3: #include src/ksp/ksp/kspimpl.h
7: /*@C
8: KSPInitialResidual - Computes the residual.
10: Collective on KSP
12: Input Parameters:
13: + vsoln - solution to use in computing residual
14: . vt1, vt2 - temporary work vectors
15: . vres - calculated residual
16: - vb - right-hand-side vector
18: Notes:
19: This routine assumes that an iterative method, designed for
20: $ A x = b
21: will be used with a preconditioner, C, such that the actual problem is either
22: $ AC u = f (right preconditioning) or
23: $ CA x = Cf (left preconditioning).
25: Level: developer
27: .keywords: KSP, residual
29: .seealso: KSPMonitor()
30: @*/
31: int KSPInitialResidual(KSP ksp,Vec vsoln,Vec vt1,Vec vt2,Vec vres,Vec vb)
32: {
33: PetscScalar mone = -1.0;
34: MatStructure pflag;
35: Mat Amat,Pmat;
36: int ierr;
43: PCGetOperators(ksp->B,&Amat,&Pmat,&pflag);
44: if (!ksp->guess_zero) {
45: /* skip right scaling since current guess already has it */
46: KSP_MatMult(ksp,Amat,vsoln,vt1);
47: VecCopy(vb,vt2);
48: VecAXPY(&mone,vt1,vt2);
49: (ksp->pc_side == PC_RIGHT)?(VecCopy(vt2,vres)):(KSP_PCApply(ksp,ksp->B,vt2,vres));
50: PCDiagonalScaleLeft(ksp->B,vres,vres);
51: } else {
52: if (ksp->pc_side == PC_RIGHT) {
53: PCDiagonalScaleLeft(ksp->B,vb,vres);
54: } else if (ksp->pc_side == PC_LEFT) {
55: KSP_PCApply(ksp,ksp->B,vb,vres);
56: PCDiagonalScaleLeft(ksp->B,vres,vres);
57: } else if (ksp->pc_side == PC_SYMMETRIC) {
58: PCApplySymmetricLeft(ksp->B, vb, vres);
59: } else {
60: SETERRQ1(PETSC_ERR_SUP, "Invalid preconditioning side %d", ksp->pc_side);
61: }
63: }
64: return(0);
65: }
69: /*@
70: KSPUnwindPreconditioner - Unwinds the preconditioning in the solution. That is,
71: takes solution to the preconditioned problem and gets the solution to the
72: original problem from it.
74: Collective on KSP
76: Input Parameters:
77: + ksp - iterative context
78: . vsoln - solution vector
79: - vt1 - temporary work vector
81: Output Parameter:
82: . vsoln - contains solution on output
84: Notes:
85: If preconditioning either symmetrically or on the right, this routine solves
86: for the correction to the unpreconditioned problem. If preconditioning on
87: the left, nothing is done.
89: Level: advanced
91: .keywords: KSP, unwind, preconditioner
93: .seealso: KSPSetPreconditionerSide()
94: @*/
95: int KSPUnwindPreconditioner(KSP ksp,Vec vsoln,Vec vt1)
96: {
102: if (ksp->pc_side == PC_RIGHT) {
103: KSP_PCApply(ksp,ksp->B,vsoln,vt1);
104: PCDiagonalScaleRight(ksp->B,vt1,vsoln);
105: } else if (ksp->pc_side == PC_SYMMETRIC) {
106: PCApplySymmetricRight(ksp->B,vsoln,vt1);
107: VecCopy(vt1,vsoln);
108: } else {
109: PCDiagonalScaleRight(ksp->B,vsoln,vsoln);
110: }
111: return(0);
112: }