123 const Scalar breakdownEps = std::numeric_limits<Scalar>::min() * Scalar(1e10);
131 report_.timer().start();
145 preconditioner_.pre(x, r);
152 for (
unsigned i = 0; i < x.size(); ++i) {
153 const auto& u = x[i];
155 throw std::logic_error(
"The preconditioner is assumed not to modify the initial solution!");
159 convergenceCriterion_.setInitial(x, r);
160 if (convergenceCriterion_.converged()) {
161 report_.setConverged(
true);
162 return report_.converged();
165 if (verbosity_ > 0) {
166 std::cout <<
"-------- BiCGStabSolver --------" << std::endl;
167 convergenceCriterion_.printInitial();
174 const Vector& r0hat = *b_;
193 unsigned n = x.size();
195 for (; report_.iterations() < maxIterations_; report_.increment()) {
197 Scalar rho_i = scalarProduct_.dot(r0hat, r);
200 if (std::abs(rho) <= breakdownEps || std::abs(omega) <= breakdownEps)
201 throw NumericalProblem(
"Breakdown of the BiCGStab solver (division by zero)");
202 Scalar beta = (rho_i/rho)*(alpha/omega);
211 for (
unsigned i = 0; i < n; ++i) {
225 preconditioner_.apply(y, p);
231 Scalar denom = scalarProduct_.dot(r0hat, v);
232 if (std::abs(denom) <= breakdownEps)
233 throw NumericalProblem(
"Breakdown of the BiCGStab solver (division by zero)");
235 if (std::abs(alpha) <= breakdownEps)
236 throw NumericalProblem(
"Breakdown of the BiCGStab solver (stagnation detected)");
240 for (
unsigned i = 0; i < n; ++i) {
253 convergenceCriterion_.update(h, y, s);
254 if (convergenceCriterion_.converged()) {
255 if (verbosity_ > 0) {
256 convergenceCriterion_.print(report_.iterations() + 0.5);
257 std::cout <<
"-------- /BiCGStabSolver --------" << std::endl;
261 preconditioner_.post(x);
262 report_.setConverged(
true);
263 return report_.converged();
265 else if (convergenceCriterion_.failed()) {
266 if (verbosity_ > 0) {
267 convergenceCriterion_.print(report_.iterations() + 0.5);
268 std::cout <<
"-------- /BiCGStabSolver --------" << std::endl;
271 report_.setConverged(
false);
272 return report_.converged();
276 convergenceCriterion_.print(report_.iterations() + 0.5);
280 preconditioner_.apply(z, s);
287 denom = scalarProduct_.dot(t, t);
288 if (std::abs(denom) <= breakdownEps)
289 throw NumericalProblem(
"Breakdown of the BiCGStab solver (division by zero)");
290 omega = scalarProduct_.dot(t, s)/denom;
291 if (std::abs(omega) <= breakdownEps)
292 throw NumericalProblem(
"Breakdown of the BiCGStab solver (stagnation detected)");
299 convergenceCriterion_.update(x, z, r);
300 if (convergenceCriterion_.converged()) {
301 if (verbosity_ > 0) {
302 convergenceCriterion_.print(1.0 + report_.iterations());
303 std::cout <<
"-------- /BiCGStabSolver --------" << std::endl;
306 preconditioner_.post(x);
307 report_.setConverged(
true);
308 return report_.converged();
310 else if (convergenceCriterion_.failed()) {
311 if (verbosity_ > 0) {
312 convergenceCriterion_.print(1.0 + report_.iterations());
313 std::cout <<
"-------- /BiCGStabSolver --------" << std::endl;
316 report_.setConverged(
false);
317 return report_.converged();
321 convergenceCriterion_.print(1.0 + report_.iterations());
328 report_.setConverged(
false);
329 return report_.converged();