bool LinearSolver::solve(VECTOR & x, const VECTOR & b) { SPAR_MAT * A = NULL; rhs_ = &b; initialized_ = false; initialize(); if (num_unknowns() == 0) { set_fixed_values(x); return true; } const VECTOR & r = *b_; if (solverType_ == ITERATIVE_SOLVE_SYMMETRIC) { if (parallel_) { A = new PAR_SPAR_MAT(LammpsInterface::instance()->world(), *matrixSparse_); } else { A = new SPAR_MAT(*matrixSparse_); } DIAG_MAT & PC = matrixDiagonal_; int niter = maxIterations_; double tol = tol_; int convergence = CG(*A, x, r, PC, niter, tol);// CG changes niter, tol if (convergence>0) { stringstream ss; ss << "CG solve did not converge,"; ss << " iterations: " << niter; ss << " residual: " << tol; throw ATC_Error(ss.str()); } } else if (solverType_ == ITERATIVE_SOLVE) { if (parallel_) { A = new PAR_SPAR_MAT(LammpsInterface::instance()->world(), *matrixSparse_); } else { A = new SPAR_MAT(*matrixSparse_); } const DIAG_MAT & PC = matrixDiagonal_; int iterations = maxIterations_; int restarts = maxRestarts_; double tol = tol_; DENS_MAT H(maxRestarts_+1, maxRestarts_); DENS_VEC xx(nVariables_); DENS_VEC bb; bb = b; int convergence = GMRES(*A, xx, bb, PC, H, restarts, iterations, tol); if (convergence>0) { stringstream ss; ss << "GMRES greens_function solve did not converge,"; ss << " iterations: " << iterations; ss << " residual: " << tol; throw ATC_Error(ss.str()); } x.copy(xx.ptr(),xx.nRows()); } else { // DIRECT_SOLVE const DENS_MAT & invA = matrixInverse_; if (constraintHandlerType_ == CONDENSE_CONSTRAINTS) { DENS_MAT xx = invA*r; int i = 0; set<int>::const_iterator itr; for (itr = freeSet_.begin(); itr != freeSet_.end(); itr++,i++) { int ii = *itr; x(ii) = xx(i,0); } set_fixed_values(x); } else { DENS_VEC xx = invA*r; for (int i = 0; i < xx.nRows(); i++) { x(i) = xx(i); } } } delete A; return true; }