LinearSolverISTL::LinearSolverResults LinearSolverISTL::solve(int size, int nonzeros, const int* ia, const int* ja, const double* sa, const double* rhs, double* solution) { // Build ISTL structures from input. // System matrix Mat A(size, size, nonzeros, Mat::row_wise); for (Mat::CreateIterator row = A.createbegin(); row != A.createend(); ++row) { int ri = row.index(); for (int i = ia[ri]; i < ia[ri + 1]; ++i) { row.insert(ja[i]); } } for (int ri = 0; ri < size; ++ri) { for (int i = ia[ri]; i < ia[ri + 1]; ++i) { A[ri][ja[i]] = sa[i]; } } // System RHS Vector b(size); std::copy(rhs, rhs + size, b.begin()); // System solution Vector x(size); x = 0.0; if (linsolver_save_system_) { // Save system to files. writeMatrixToMatlab(A, linsolver_save_filename_ + "-mat"); std::string rhsfile(linsolver_save_filename_ + "-rhs"); std::ofstream rhsf(rhsfile.c_str()); rhsf.precision(15); rhsf.setf(std::ios::scientific | std::ios::showpos); std::copy(b.begin(), b.end(), std::ostream_iterator<VectorBlockType>(rhsf, "\n")); } int maxit = linsolver_max_iterations_; if (maxit == 0) { maxit = A.N(); } LinearSolverResults res; switch (linsolver_type_) { case CG_ILU0: res = solveCG_ILU0(A, x, b, linsolver_residual_tolerance_, maxit, linsolver_verbosity_); break; case CG_AMG: res = solveCG_AMG(A, x, b, linsolver_residual_tolerance_, maxit, linsolver_verbosity_); break; case BiCGStab_ILU0: res = solveBiCGStab_ILU0(A, x, b, linsolver_residual_tolerance_, maxit, linsolver_verbosity_); break; default: std::cerr << "Unknown linsolver_type: " << int(linsolver_type_) << '\n'; throw std::runtime_error("Unknown linsolver_type"); } std::copy(x.begin(), x.end(), solution); return res; }
LinearSolverInterface::LinearSolverReport LinearSolverIstl::solve(const int size, const int nonzeros, const int* ia, const int* ja, const double* sa, const double* rhs, double* solution) const { // Build Istl structures from input. // System matrix Mat A(size, size, nonzeros, Mat::row_wise); for (Mat::CreateIterator row = A.createbegin(); row != A.createend(); ++row) { int ri = row.index(); for (int i = ia[ri]; i < ia[ri + 1]; ++i) { row.insert(ja[i]); } } for (int ri = 0; ri < size; ++ri) { for (int i = ia[ri]; i < ia[ri + 1]; ++i) { A[ri][ja[i]] = sa[i]; } } // System RHS Vector b(size); std::copy(rhs, rhs + size, b.begin()); // System solution Vector x(size); x = 0.0; if (linsolver_save_system_) { // Save system to files. writeMatrixToMatlab(A, linsolver_save_filename_ + "-mat"); std::string rhsfile(linsolver_save_filename_ + "-rhs"); std::ofstream rhsf(rhsfile.c_str()); rhsf.precision(15); rhsf.setf(std::ios::scientific | std::ios::showpos); std::copy(b.begin(), b.end(), std::ostream_iterator<VectorBlockType>(rhsf, "\n")); } int maxit = linsolver_max_iterations_; if (maxit == 0) { maxit = 5000; } LinearSolverReport res; switch (linsolver_type_) { case CG_ILU0: res = solveCG_ILU0(A, x, b, linsolver_residual_tolerance_, maxit, linsolver_verbosity_); break; case CG_AMG: res = solveCG_AMG(A, x, b, linsolver_residual_tolerance_, maxit, linsolver_verbosity_); break; case KAMG: #ifdef HAS_DUNE_FAST_AMG res = solveKAMG(A, x, b, linsolver_residual_tolerance_, maxit, linsolver_verbosity_); #else throw std::runtime_error("KAMG not supported with this version of DUNE"); #endif break; case FastAMG: #ifdef HAS_DUNE_FAST_AMG res = solveFastAMG(A, x, b, linsolver_residual_tolerance_, maxit, linsolver_verbosity_); #else if(linsolver_verbosity_) std::cerr<<"Fast AMG is not available; falling back to CG preconditioned with the normal one"<<std::endl; res = solveCG_AMG(A, x, b, linsolver_residual_tolerance_, maxit, linsolver_verbosity_); #endif break; case BiCGStab_ILU0: res = solveBiCGStab_ILU0(A, x, b, linsolver_residual_tolerance_, maxit, linsolver_verbosity_); break; default: std::cerr << "Unknown linsolver_type: " << int(linsolver_type_) << '\n'; throw std::runtime_error("Unknown linsolver_type"); } std::copy(x.begin(), x.end(), solution); return res; }