@@ -24,6 +24,7 @@ class SolverCG : public Solver<howmany, n_str> {
2424 RealArray d_real;
2525 RealArray rnew_real;
2626 double alpha_warm{0.1 };
27+ bool ls_converged{true };
2728
2829 void internalSolve ();
2930 void LineSearchSecant ();
@@ -91,7 +92,7 @@ void SolverCG<howmany, n_str>::internalSolve()
9192 delta0 = delta;
9293 delta = dotProduct (v_r_real, s_real);
9394
94- d_real = s_real + fmax (0 , (delta - deltamid) / delta0) * d_real;
95+ d_real = s_real + (ls_converged ? fmax (0.0 , (delta - deltamid) / delta0) : 0.0 ) * d_real;
9596
9697 if (islinear && !this ->isMixedBCActive ()) {
9798 Matrix<double , howmany * 8 , 1 > res_e;
@@ -119,44 +120,43 @@ void SolverCG<howmany, n_str>::internalSolve()
119120template <int howmany, int n_str>
120121void SolverCG<howmany, n_str>::LineSearchSecant()
121122{
122- double err = 10.0 ;
123123 const int MaxIter = this ->reader .ls_max_iter ;
124124 const double tol = this ->reader .ls_tol ;
125125 int _iter = 0 ;
126126 double alpha_prev = 0.0 ;
127127 double alpha_curr = alpha_warm;
128128
129- double rpd = dotProduct (v_r_real, d_real);
129+ const double rpd0 = dotProduct (v_r_real, d_real);
130+ double rpd = rpd0;
130131 v_u_real += d_real * alpha_curr;
131132 this ->updateMixedBC ();
132133 this ->template compute_residual <0 >(rnew_real, v_u_real);
133134 double r1pd = dotProduct (rnew_real, d_real);
134135
135136 double denom, alpha_next;
136- while (_iter < MaxIter && err > tol) {
137+ while (_iter < MaxIter && fabs (r1pd) > tol * fabs (rpd0) ) {
137138 denom = r1pd - rpd;
138139 if (fabs (denom) < 1e-14 * (fabs (r1pd) + fabs (rpd)))
139140 break ;
140141
141142 alpha_next = alpha_curr - r1pd * (alpha_curr - alpha_prev) / denom;
142- if (alpha_next <= 0.0 )
143+ if (alpha_next <= 0.0 || alpha_next > 10.0 )
143144 alpha_next = 0.5 * (alpha_prev + alpha_curr);
144- err = fabs (alpha_next - alpha_curr);
145145
146146 v_u_real += d_real * (alpha_next - alpha_curr);
147147 alpha_prev = alpha_curr;
148148 rpd = r1pd;
149149 alpha_curr = alpha_next;
150150 _iter++;
151151
152- this ->updateMixedBC ();
153152 this ->template compute_residual <0 >(rnew_real, v_u_real);
154153 r1pd = dotProduct (rnew_real, d_real);
155154 }
156- alpha_warm = (_iter == MaxIter && err > tol) ? 0.1 : alpha_curr;
157- v_r_real = rnew_real;
155+ ls_converged = (fabs (r1pd) <= tol * fabs (rpd0));
156+ alpha_warm = ls_converged ? alpha_curr : 0.1 ;
157+ v_r_real = rnew_real;
158158 if (this ->world_rank == 0 )
159- printf (" line search iter %i, alpha %f - error %e - " , _iter, alpha_curr, err );
159+ printf (" line search iter %i, alpha %f - error %e - " , _iter, alpha_curr, fabs (rpd0) > 0.0 ? fabs (r1pd) / fabs (rpd0) : 0.0 );
160160}
161161
162162template <int howmany, int n_str>
0 commit comments