void LisMatrix::multiply(const LisVector &x, LisVector &y) const { if (!_is_assembled) throw std::logic_error("LisMatrix::matvec(): matrix not assembled."); int ierr = lis_matvec(_AA, const_cast<LisVector*>(&x)->getRawVector(), y.getRawVector()); checkLisError(ierr); }
void applyKnownSolution(LisMatrix &A, LisVector &b, const std::vector<std::size_t> &vec_knownX_id, const std::vector<double> &vec_knownX_x, double penalty_scaling) { //Use penalty parameter const double max_diag_coeff = A.getMaxDiagCoeff(); const double penalty = max_diag_coeff * penalty_scaling; INFO("-> max. absolute value of diagonal entries = %e", max_diag_coeff); INFO("-> penalty scaling = %e", penalty_scaling); const std::size_t n_bc = vec_knownX_id.size(); for (std::size_t i_bc=0; i_bc<n_bc; i_bc++) { const std::size_t rowId = vec_knownX_id[i_bc]; const double x = vec_knownX_x[i_bc]; //A(k, k) = penalty A.setValue(rowId, rowId, penalty); //b(k) = x*penalty b.set(rowId, x*penalty); } }
void LisLinearSolver::solve(LisVector &b, LisVector &x) { finalizeMatrixAssembly(_A); INFO("------------------------------------------------------------------"); INFO("*** LIS solver computation"); #ifdef _OPENMP INFO("-> max number of threads = %d", omp_get_num_procs()); INFO("-> number of threads = %d", omp_get_max_threads()); #endif // configure option std::string solver_options; if (_option.solver_precon_arg.empty()) { std::stringstream ss; ss << "-i " << static_cast<int>(_option.solver_type); ss << " -p " << static_cast<int>(_option.precon_type); if (!_option.extra_arg.empty()) ss << " " << _option.extra_arg; solver_options = ss.str(); } else { solver_options = _option.solver_precon_arg; } std::string tol_option; { std::stringstream ss; ss << "-tol " << _option.error_tolerance; ss << " -maxiter " << _option.max_iterations; ss << " -initx_zeros 0"; //0: use given x as initial guess, 1: x0=0 #ifdef _OPENMP const int nthreads = omp_get_max_threads(); ss << " -omp_num_threads " << nthreads; #endif tol_option = ss.str(); } // Create solver LIS_SOLVER solver; int ierr = lis_solver_create(&solver); checkLisError(ierr); ierr = lis_solver_set_option(const_cast<char*>(solver_options.c_str()), solver); checkLisError(ierr); ierr = lis_solver_set_option(const_cast<char*>(tol_option.c_str()), solver); checkLisError(ierr); ierr = lis_solver_set_option(const_cast<char*>("-print mem"), solver); checkLisError(ierr); ierr = lis_solver_set_optionC(solver); checkLisError(ierr); // solve INFO("-> solve"); ierr = lis_solve(_A.getRawMatrix(), b.getRawVector(), x.getRawVector(), solver); checkLisError(ierr); int iter = 0; double resid = 0.0; ierr = lis_solver_get_iter(solver, &iter); checkLisError(ierr); ierr = lis_solver_get_residualnorm(solver, &resid); checkLisError(ierr); INFO("\t iteration: %d/%ld\n", iter, _option.max_iterations); INFO("\t residual: %e\n", resid); // Clear solver ierr = lis_solver_destroy(solver); checkLisError(ierr); INFO("------------------------------------------------------------------"); }
bool LisLinearSolver::solve(LisMatrix &A, LisVector &b, LisVector &x) { finalizeMatrixAssembly(A); INFO("------------------------------------------------------------------"); INFO("*** LIS solver computation"); // Create solver LIS_SOLVER solver; int ierr = lis_solver_create(&solver); if (!checkLisError(ierr)) return false; lis_solver_set_option( const_cast<char*>(_lis_option._option_string.c_str()), solver); #ifdef _OPENMP INFO("-> number of threads: %i", (int) omp_get_max_threads()); #endif { int precon; ierr = lis_solver_get_precon(solver, &precon); INFO("-> precon: %i", precon); } { int slv; ierr = lis_solver_get_solver(solver, &slv); INFO("-> solver: %i", slv); } // solve INFO("-> solve"); ierr = lis_solve(A.getRawMatrix(), b.getRawVector(), x.getRawVector(), solver); if (!checkLisError(ierr)) return false; LIS_INT linear_solver_status; ierr = lis_solver_get_status(solver, &linear_solver_status); if (!checkLisError(ierr)) return false; INFO("-> status: %d", linear_solver_status); { int iter = 0; ierr = lis_solver_get_iter(solver, &iter); if (!checkLisError(ierr)) return false; INFO("-> iteration: %d", iter); } { double resid = 0.0; ierr = lis_solver_get_residualnorm(solver, &resid); if (!checkLisError(ierr)) return false; INFO("-> residual: %g", resid); } { double time, itime, ptime, p_ctime, p_itime; ierr = lis_solver_get_timeex(solver, &time, &itime, &ptime, &p_ctime, &p_itime); if (!checkLisError(ierr)) return false; INFO("-> time total (s): %g", time); INFO("-> time iterations (s): %g", itime); INFO("-> time preconditioning (s): %g", ptime); INFO("-> time precond. create (s): %g", p_ctime); INFO("-> time precond. iter (s): %g", p_itime); } // Clear solver ierr = lis_solver_destroy(solver); if (!checkLisError(ierr)) return false; INFO("------------------------------------------------------------------"); return linear_solver_status == LIS_SUCCESS; }