void LinearSolver::greens_function(int I, VECTOR & G_I) { SPAR_MAT * A = NULL; initialize_matrix(); initialize_inverse(); G_I.reset(nVariables_); VECTOR & x = G_I; if (solverType_ == ITERATIVE_SOLVE_SYMMETRIC) { DENS_VEC b(nVariables_); b = 0.0; b(I) = 1.0; if (parallel_) { A = new PAR_SPAR_MAT(LammpsInterface::instance()->world(), *matrixSparse_); } else { A = new SPAR_MAT(*matrixSparse_); } const DIAG_MAT & PC = matrixDiagonal_; int niter = maxIterations_; double tol = tol_; int convergence = CG(*A, x, b, PC, niter, tol); if (convergence>0) { stringstream ss; ss << "CG greens_function solve did not converge,"; ss << " iterations: " << niter; ss << " residual: " << tol; throw ATC_Error(ss.str()); } } else if (solverType_ == ITERATIVE_SOLVE) { DENS_VEC b(nVariables_); b = 0.0; b(I) = 1.0; // VECTOR & bb = b; if (parallel_) { A = new PAR_SPAR_MAT(LammpsInterface::instance()->world(), *matrixSparse_); } else { A = new SPAR_MAT(*matrixSparse_); } // const DENS_MAT A = matrixSparse_->dense_copy(); const DIAG_MAT & PC = matrixDiagonal_; int iterations = maxIterations_; int restarts = maxRestarts_; double tol = tol_; DENS_MAT H(maxRestarts_+1, maxRestarts_); DENS_VEC xx(nVariables_); int convergence = GMRES(*A, xx, b, 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 { const DENS_MAT & invA = matrixInverse_; if (constraintHandlerType_ == CONDENSE_CONSTRAINTS) { set<int>::const_iterator itr; for (itr = fixedSet_.begin(); itr != fixedSet_.end(); itr++) { int ii = *itr; x(ii) = 0; } itr = freeSet_.find(I); if (itr !=freeSet_.end() ) { int j = freeGlobalToCondensedMap_[I]; int i = 0; for (itr = freeSet_.begin(); itr != freeSet_.end(); itr++,i++) { int ii = *itr; x(ii) = invA(j,i); } } } else { for (int i = 0; i < nVariables_; ++i) x(i) = invA(I,i); } } delete A; }