-----------------------------------------------------------------------------
| 688 | } |
| 689 | //----------------------------------------------------------------------------- |
| 690 | int petsc::KrylovSolver::solve(Vec x, const Vec b, bool transpose) const |
| 691 | { |
| 692 | common::Timer timer("PETSc Krylov solver"); |
| 693 | assert(x); |
| 694 | assert(b); |
| 695 | |
| 696 | // Get PETSc operators |
| 697 | Mat _A, _P; |
| 698 | KSPGetOperators(_ksp, &_A, &_P); |
| 699 | assert(_A); |
| 700 | |
| 701 | PetscErrorCode ierr; |
| 702 | |
| 703 | // Solve linear system |
| 704 | spdlog::info("PETSc Krylov solver starting to solve system."); |
| 705 | |
| 706 | // Solve system |
| 707 | if (!transpose) |
| 708 | { |
| 709 | ierr = KSPSolve(_ksp, b, x); |
| 710 | if (ierr != 0) |
| 711 | petsc::error(ierr, __FILE__, "KSPSolve"); |
| 712 | } |
| 713 | else |
| 714 | { |
| 715 | ierr = KSPSolveTranspose(_ksp, b, x); |
| 716 | if (ierr != 0) |
| 717 | petsc::error(ierr, __FILE__, "KSPSolve"); |
| 718 | } |
| 719 | |
| 720 | // Get the number of iterations |
| 721 | PetscInt num_iterations = 0; |
| 722 | ierr = KSPGetIterationNumber(_ksp, &num_iterations); |
| 723 | if (ierr != 0) |
| 724 | petsc::error(ierr, __FILE__, "KSPGetIterationNumber"); |
| 725 | |
| 726 | // Check if the solution converged and print error/warning if not |
| 727 | // converged |
| 728 | KSPConvergedReason reason; |
| 729 | ierr = KSPGetConvergedReason(_ksp, &reason); |
| 730 | if (ierr != 0) |
| 731 | petsc::error(ierr, __FILE__, "KSPGetConvergedReason"); |
| 732 | if (reason < 0) |
| 733 | { |
| 734 | /* |
| 735 | // Get solver residual norm |
| 736 | double rnorm = 0; |
| 737 | ierr = KSPGetResidualNorm(_ksp, &rnorm); |
| 738 | if (ierr != 0) error(ierr, __FILE__, "KSPGetResidualNorm"); |
| 739 | const char *reason_str = KSPConvergedReasons[reason]; |
| 740 | bool error_on_nonconvergence = |
| 741 | this->parameters["error_on_nonconvergence"].is_set() ? |
| 742 | this->parameters["error_on_nonconvergence"] : true; |
| 743 | if (error_on_nonconvergence) |
| 744 | { |
| 745 | log::dolfin_error("PETScKrylovSolver.cpp", |
| 746 | "solve linear system using PETSc Krylov solver", |
| 747 | "Solution failed to converge in %i iterations (PETSc reason |
nothing calls this directly
no outgoing calls
no test coverage detected