102 if (a_its < 0) { a_its = m_maxiter; }
107 V r = m_linop->makeVecRHS();
108 V
z = m_linop->makeVecLHS();
109 V p = m_linop->makeVecLHS();
110 V q = m_linop->makeVecRHS();
112 if (m_nonzero_guess) {
114 m_linop->assign(p, a_sol);
115 m_linop->apply(q, p);
116 m_linop->linComb(r,
RT(1), a_rhs,
RT(-1), q);
118 m_linop->setToZero(a_sol);
119 m_linop->assign(r, a_rhs);
122 RT rnorm = m_linop->norm2(r);
123 RT const rnorm0 = rnorm;
127 amrex::Print() <<
"PCG: Initial residual (error0) = " << rnorm0 <<
'\n';
130 if (rnorm0 ==
RT(0) || rnorm0 < m_atol) {
135 auto converged = [&] (
RT rn) {
136 return rn ==
RT(0) || rn < m_rtol*rnorm0 || rn < m_atol;
139 m_linop->precond(
z, r);
140 m_linop->assign(p,
z);
141 RT rz = m_linop->dotProduct(r,
z);
144 RT const sgn = (rz <
RT(0)) ?
RT(-1) :
RT(1);
145 if (rz ==
RT(0) || !amrex::isfinite(rz)) { m_status = 3; }
147 for (
int iter = 1; iter <= a_its && m_status == -1; ++iter)
149 m_linop->apply(q, p);
150 RT const pq = m_linop->dotProduct(p, q);
151 if (sgn*pq <=
RT(0) || !amrex::isfinite(pq)) { m_status = 2;
break; }
152 RT const alpha = rz/pq;
154 m_linop->increment(a_sol, p, alpha);
155 m_linop->increment(r, q, -alpha);
157 rnorm = m_linop->norm2(r);
162 amrex::Print() <<
"PCG: Iteration " << std::setw(11) << iter
163 <<
" rel. err. " << rnorm/rnorm0 <<
'\n';
166 if (converged(rnorm)) { m_status = 0;
break; }
167 if (!amrex::isfinite(rnorm)) { m_status = 3;
break; }
168 if (iter == a_its) {
break; }
170 m_linop->precond(
z, r);
171 RT const rz_new = m_linop->dotProduct(r,
z);
172 if (sgn*rz_new <=
RT(0) || !amrex::isfinite(rz_new)) { m_status = 3;
break; }
173 RT const beta = rz_new/rz;
176 m_linop->scale(p,
beta);
177 m_linop->increment(p,
z,
RT(1));
180 if (m_status == -1) { m_status = 1; }
183 amrex::Print() <<
"PCG: Final: Iteration " << std::setw(4) << m_its
184 <<
" rel. err. " << rnorm/rnorm0 <<
'\n';
187 if (m_status != 0 && m_verbose > 0) {
188 amrex::Print() <<
"PCG: Failed to converge, status = " << m_status <<
'\n';
void solve(V &a_sol, V const &a_rhs, RT a_tol_rel, RT a_tol_abs, int a_its=-1)
Solve the linear system.
Definition AMReX_PCG.H:94