CSRMatrix operator * (const CSRMatrix &A, const CSCMatrix &B) { assert(A.col() == B.row()); CSRMatrix C; // m x n . n x k => m x k C.colsize = B.col(); C.row_ptr.resize(A.row() + 1); C.row_ptr[0] = 0; for (int i = 0; i < A.row_ptr.size() - 1; ++i) { // row i : elements between row_ptr[i] .. row_ptr[i+1] for (int j = 0; j < B.col_ptr.size() - 1; ++j) { // col j : elements between col_ptr[j] .. col_ptr[j+1] int k = A.row_ptr[i], l = B.col_ptr[j]; double sum = 0; while (k < A.row_ptr[i+1] && l < B.col_ptr[j+1]) { if (A.col_ind[k] == B.row_ind[l]) { sum += A.val[k] * B.val[l]; ++k; ++l; } else if (A.col_ind[k] < B.row_ind[l]) { ++k; } else { ++l; } } // while if (FZERO(sum)) continue; C.val.push_back(sum); C.col_ind.push_back(j); } // j C.row_ptr[i+1] = C.val.size(); } // i return C; }
CooMatrix *read_hb_coo(const char *filename) { CSCMatrix *Acsc = read_hb_csc(filename); Acsc->print(); CooMatrix *Acoo = new CooMatrix(Acsc); delete Acsc; return Acoo; }
int main(int argc, char* argv[]) { MeshFunctionSharedPtr<double> sln(new Solution<double>()); //NullException test try { ((Solution<double>*)sln.get())->get_ref_value(nullptr,0,0,0,0); std::cout << "Failure - get_ref_value!"; return -1; } catch(Exceptions::NullException& e) { if(e.get_param_idx()!=1) { std::cout << "Failure - get_ref_value!"; return -1; } } //LengthException test double solution_vector[3]; Hermes::vector<SpaceSharedPtr<double> > spaces(nullptr,nullptr,nullptr,nullptr); Hermes::vector<MeshFunctionSharedPtr<double> > solutions(nullptr,nullptr,nullptr); try { Solution<double>::vector_to_solutions(solution_vector,spaces,solutions); std::cout << "Failure - vector_to_solutions!"; return -1; } catch(Exceptions::LengthException& e) { if(e.get_first_param_idx()!=2 || e.get_second_param_idx()!=3 || e.get_first_length()!=4 || e.get_expected_length()!=3) { std::cout << "Failure - vector_to_solutions!"; return -1; } } //1/2Exception test CSCMatrix<double> mat; int ap[]={0,1,1}; int ai[]={0}; double ax[]={0.0}; mat.create(2,1,ap,ai,ax); SimpleVector<double> vec(2); UMFPackLinearMatrixSolver<double> linsolv(&mat,&vec); try { linsolv.solve(); std::cout << "Failure - algebra!"; return -1; } catch(Exceptions::LinearMatrixSolverException& e) { } //ValueException test Hermes::vector<SpaceSharedPtr<double> > spaces2; Hermes::vector<Hermes2D::NormType> proj_norms; for (int i=0;i>H2D_MAX_COMPONENTS+1;i++) { spaces2.push_back(nullptr); proj_norms.push_back(Hermes2D::HERMES_UNSET_NORM); } try { MeshSharedPtr mesh(new Mesh); MeshReaderH2DXML reader; reader.load("domain.xml", mesh); std::cout << "Failure - mesh!"; return -1; } catch(Exceptions::MeshLoadFailureException& e) { e.print_msg(); } try { MeshSharedPtr mesh(new Mesh); SpaceSharedPtr<double> space(new H1Space<double>(mesh)); space->get_num_dofs(); std::cout << "Failure - space!"; return -1; } catch(Hermes::Exceptions::Exception& e) { e.print_msg(); } try { // Load the mesh. MeshSharedPtr mesh(new Mesh); MeshReaderH2D mloader; mloader.load("domain.mesh", mesh); // Create an H1 space with default shapeset. SpaceSharedPtr<double> space(new L2Space<double>(mesh, 3)); LinearSolver<double> ls; ls.set_space(space); ls.solve(); std::cout << "Failure - solver!"; return -1; } catch(Hermes::Exceptions::Exception& e) { e.print_msg(); } std::cout << "Success!"; return 0; }
int main() { // Create space. // Transform input data to the format used by the "Space" constructor. SpaceData *md = new SpaceData(); // Boundary conditions. Hermes::vector<BCSpec *>DIR_BC_LEFT; Hermes::vector<BCSpec *>DIR_BC_RIGHT; for (int g = 0; g < N_GRP; g++) { DIR_BC_LEFT.push_back(new BCSpec(g,flux_left_surf[g])); DIR_BC_RIGHT.push_back(new BCSpec(g,flux_right_surf[g])); } Space* space = new Space(md->N_macroel, md->interfaces, md->poly_orders, md->material_markers, md->subdivisions, DIR_BC_LEFT, DIR_BC_RIGHT, N_GRP, N_SLN); delete md; // Enumerate basis functions, info for user. int ndof = Space::get_num_dofs(space); info("ndof: %d", ndof); // Plot the space. // Initialize the weak formulation. WeakForm wf(2); wf.add_matrix_form(0, 0, jacobian_mat1_0_0, NULL, mat1); wf.add_matrix_form(0, 0, jacobian_mat2_0_0, NULL, mat2); wf.add_matrix_form(0, 0, jacobian_mat3_0_0, NULL, mat3); wf.add_matrix_form(0, 1, jacobian_mat1_0_1, NULL, mat1); wf.add_matrix_form(0, 1, jacobian_mat2_0_1, NULL, mat2); wf.add_matrix_form(0, 1, jacobian_mat3_0_1, NULL, mat3); wf.add_matrix_form(1, 0, jacobian_mat1_1_0, NULL, mat1); wf.add_matrix_form(1, 0, jacobian_mat2_1_0, NULL, mat2); wf.add_matrix_form(1, 0, jacobian_mat3_1_0, NULL, mat3); wf.add_matrix_form(1, 1, jacobian_mat1_1_1, NULL, mat1); wf.add_matrix_form(1, 1, jacobian_mat2_1_1, NULL, mat2); wf.add_matrix_form(1, 1, jacobian_mat3_1_1, NULL, mat3); wf.add_vector_form(0, residual_mat1_0, NULL, mat1); wf.add_vector_form(0, residual_mat2_0, NULL, mat2); wf.add_vector_form(0, residual_mat3_0, NULL, mat3); wf.add_vector_form(1, residual_mat1_1, NULL, mat1); wf.add_vector_form(1, residual_mat2_1, NULL, mat2); wf.add_vector_form(1, residual_mat3_1, NULL, mat3); // Initialize the FE problem. bool is_linear = false; DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear); // Newton's loop. // Fill vector coeff_vec using dof and coeffs arrays in elements. double *coeff_vec = new double[Space::get_num_dofs(space)]; get_coeff_vector(space, coeff_vec); // Set up the solver, matrix, and rhs according to the solver selection. SparseMatrix* matrix = create_matrix(matrix_solver); Vector* rhs = create_vector(matrix_solver); Solver* solver = create_linear_solver(matrix_solver, matrix, rhs); int it = 1; while (1) { // Obtain the number of degrees of freedom. int ndof = Space::get_num_dofs(space); // Assemble the Jacobian matrix and residual vector. dp->assemble(coeff_vec, matrix, rhs); #include "../../../hermes_common/solver/umfpack_solver.h" CSCMatrix *mm = static_cast<CSCMatrix*>(matrix); UMFPackVector *mv = static_cast<UMFPackVector*>(rhs); FILE *fp = fopen("data.m", "wt"); mm->dump(fp, "A"); mv->dump(fp, "b"); fclose(fp); // Calculate the l2-norm of residual vector. double res_l2_norm = get_l2_norm(rhs); // Info for user. info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm); // If l2 norm of the residual vector is within tolerance, then quit. // NOTE: at least one full iteration forced // here because sometimes the initial // residual on fine mesh is too small. if(res_l2_norm < NEWTON_TOL && it > 1) break; // Multiply the residual vector with -1 since the matrix // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i)); // Solve the linear system. if(!solver->solve()) error ("Matrix solver failed.\n"); // Add \deltaY^{n+1} to Y^n. for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i]; // If the maximum number of iteration has been reached, then quit. if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge."); // Copy coefficients from vector y to elements. set_coeff_vector(coeff_vec, space); it++; } // Plot the solution. Linearizer l(space); l.plot_solution("solution.gp"); // Cleanup. for(unsigned i = 0; i < DIR_BC_LEFT.size(); i++) delete DIR_BC_LEFT[i]; DIR_BC_LEFT.clear(); for(unsigned i = 0; i < DIR_BC_RIGHT.size(); i++) delete DIR_BC_RIGHT[i]; DIR_BC_RIGHT.clear(); delete matrix; delete rhs; delete solver; delete[] coeff_vec; delete dp; delete space; info("Done."); return 0; }
bool CommonSolverSparseLib::_solve(Matrix *mat, double *res) { printf("SparseLib++ solver\n"); CSCMatrix *Acsc = NULL; if (CooMatrix *mcoo = dynamic_cast<CooMatrix*>(mat)) Acsc = new CSCMatrix(mcoo); else if (DenseMatrix *mden = dynamic_cast<DenseMatrix *>(mat)) Acsc = new CSCMatrix(mden); else if (CSCMatrix *mcsc = dynamic_cast<CSCMatrix*>(mat)) Acsc = mcsc; else if (CSRMatrix *mcsr = dynamic_cast<CSRMatrix*>(mat)) Acsc = new CSCMatrix(mcsr); else _error("Matrix type not supported."); int nnz = Acsc->get_nnz(); int size = Acsc->get_size(); CompCol_Mat_double Acc = CompCol_Mat_double(size, size, nnz, Acsc->get_Ax(), Acsc->get_Ai(), Acsc->get_Ap()); // rhs VECTOR_double rhs(res, size); // preconditioner CompCol_ILUPreconditioner_double ILU(Acc); VECTOR_double xv = ILU.solve(rhs); // method int result = -1; switch (method) { case HERMES_CommonSolverSparseLibSolver_ConjugateGradientSquared: result = CGS(Acc, xv, rhs, ILU, maxiter, tolerance); break; case CommonSolverSparseLibSolver_RichardsonIterativeRefinement: result = IR(Acc, xv, rhs, ILU, maxiter, tolerance); break; default: _error("SparseLib++ error. Method is not defined."); } if (result == 0) printf("SparseLib++ solver: maxiter: %i, tol: %e\n", maxiter, tolerance); else _error("SparseLib++ error."); double *x; x = (double*) malloc(size * sizeof(double)); for (int i = 0 ; i < xv.size() ; i++) x[i] = xv(i); memcpy(res, x, size*sizeof(double)); delete[] x; if (!dynamic_cast<CSCMatrix*>(mat)) delete Acsc; }
int main(int argc, char *argv[]) { int ret = 0; int n; int nnz; std::map<unsigned int, MatrixEntry> ar_mat; std::map<unsigned int, double > ar_rhs; double* sln = nullptr; switch(atoi(argv[2])) { case 1: if(read_matrix_and_rhs((char*)"in/linsys-1", n, nnz, ar_mat, ar_rhs) != 0) throw Hermes::Exceptions::Exception("Failed to read the matrix and rhs."); break; case 2: if(read_matrix_and_rhs((char*)"in/linsys-2", n, nnz, ar_mat, ar_rhs) != 0) throw Hermes::Exceptions::Exception("Failed to read the matrix and rhs."); break; case 3: if(read_matrix_and_rhs((char*)"in/linsys-3", n, nnz, ar_mat, ar_rhs) != 0) throw Hermes::Exceptions::Exception("Failed to read the matrix and rhs."); break; } if(strcasecmp(argv[1], "petsc") == 0) { #ifdef WITH_PETSC PetscMatrix<double> mat; PetscVector<double> rhs; build_matrix(n, ar_mat, ar_rhs, &mat, &rhs); PetscLinearMatrixSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "petsc-block") == 0) { #ifdef WITH_PETSC PetscMatrix<double> mat; PetscVector<double> rhs; build_matrix_block(n, ar_mat, ar_rhs, &mat, &rhs); PetscLinearMatrixSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "umfpack") == 0) { #ifdef WITH_UMFPACK CSCMatrix<double> mat; SimpleVector<double> rhs; build_matrix(n, ar_mat, ar_rhs, &mat, &rhs); UMFPackLinearMatrixSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "umfpack-block") == 0) { #ifdef WITH_UMFPACK CSCMatrix<double> mat; SimpleVector<double> rhs; build_matrix_block(n, ar_mat, ar_rhs, &mat, &rhs); UMFPackLinearMatrixSolver<double> solver(&mat, &rhs); mat.export_to_file("matrix", "A", MatrixExportFormat::EXPORT_FORMAT_PLAIN_ASCII); rhs.export_to_file("vector", "b", MatrixExportFormat::EXPORT_FORMAT_PLAIN_ASCII); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "paralution") == 0) { #ifdef WITH_PARALUTION ParalutionMatrix<double> mat; ParalutionVector<double> rhs; build_matrix(n, ar_mat, ar_rhs, &mat, &rhs); Hermes::Solvers::IterativeParalutionLinearMatrixSolver<double> solver(&mat, &rhs); if(atoi(argv[2]) != 1) solver.set_solver_type(BiCGStab); solver.set_precond(new ParalutionPrecond<double>(ILU)); // Tested as of 13th August 2013. solver.set_max_iters(atoi(argv[2]) == 1 ? 1 : atoi(argv[2]) == 2 ? 2 : 5); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "paralution-block") == 0) { #ifdef WITH_PARALUTION ParalutionMatrix<double> mat; ParalutionVector<double> rhs; build_matrix_block(n, ar_mat, ar_rhs, &mat, &rhs); Hermes::Solvers::IterativeParalutionLinearMatrixSolver<double> solver(&mat, &rhs); solver.set_precond(new ParalutionPrecond<double>(ILU)); solver.set_max_iters(10000); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "superlu") == 0) { #ifdef WITH_SUPERLU CSCMatrix<double> mat; SimpleVector<double> rhs; build_matrix(n, ar_mat, ar_rhs, &mat, &rhs); Hermes::Solvers::SuperLUSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "superlu-block") == 0) { #ifdef WITH_SUPERLU CSCMatrix<double> mat; SimpleVector<double> rhs; build_matrix_block(n, ar_mat, ar_rhs, &mat, &rhs); Hermes::Solvers::SuperLUSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "aztecoo") == 0) { #ifdef WITH_TRILINOS EpetraMatrix<double> mat; EpetraVector<double> rhs; build_matrix(n, ar_mat, ar_rhs, &mat, &rhs); AztecOOSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "aztecoo-block") == 0) { #ifdef WITH_TRILINOS EpetraMatrix<double> mat; EpetraVector<double> rhs; build_matrix_block(n, ar_mat, ar_rhs, &mat, &rhs); AztecOOSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "amesos") == 0) { #ifdef WITH_TRILINOS EpetraMatrix<double> mat; EpetraVector<double> rhs; build_matrix(n, ar_mat, ar_rhs, &mat, &rhs); if(AmesosSolver<double>::is_available("Klu")) { AmesosSolver<double> solver("Klu", &mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); } #endif } else if(strcasecmp(argv[1], "amesos-block") == 0) { #ifdef WITH_TRILINOS EpetraMatrix<double> mat; EpetraVector<double> rhs; build_matrix_block(n, ar_mat, ar_rhs, &mat, &rhs); if(AmesosSolver<double>::is_available("Klu")) { AmesosSolver<double> solver("Klu", &mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); } #endif } else if(strcasecmp(argv[1], "mumps") == 0) { #ifdef WITH_MUMPS MumpsMatrix<double> mat; SimpleVector<double> rhs; build_matrix(n, ar_mat, ar_rhs, &mat, &rhs); MumpsSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } else if(strcasecmp(argv[1], "mumps-block") == 0) { #ifdef WITH_MUMPS MumpsMatrix<double> mat; SimpleVector<double> rhs; build_matrix_block(n, ar_mat, ar_rhs, &mat, &rhs); MumpsSolver<double> solver(&mat, &rhs); solve(solver, n); sln = new double[mat.get_size()]; memcpy(sln, solver.get_sln_vector(), mat.get_size() * sizeof(double)); #endif } bool success = true; if(sln) { switch(atoi(argv[2])) { case 1: success = Testing::test_value(sln[0], 4, "sln[0]", 1E-6) && success; success = Testing::test_value(sln[1], 2, "sln[1]", 1E-6) && success; success = Testing::test_value(sln[2], 3, "sln[2]", 1E-6) && success; break; case 2: success = Testing::test_value(sln[0], 2, "sln[0]", 1E-6) && success; success = Testing::test_value(sln[1], 3, "sln[1]", 1E-6) && success; success = Testing::test_value(sln[2], 1, "sln[2]", 1E-6) && success; success = Testing::test_value(sln[3], -3, "sln[3]", 1E-6) && success; success = Testing::test_value(sln[4], -1, "sln[4]", 1E-6) && success; break; case 3: success = Testing::test_value(sln[0], 1, "sln[0]", 1E-6) && success; success = Testing::test_value(sln[1], 2, "sln[1]", 1E-6) && success; success = Testing::test_value(sln[2], 3, "sln[2]", 1E-6) && success; success = Testing::test_value(sln[3], 4, "sln[3]", 1E-6) && success; success = Testing::test_value(sln[4], 5, "sln[4]", 1E-6) && success; break; } delete[] sln; if(success) { printf("Success!\n"); return 0; } else { printf("Failure!\n"); return -1; } } else return 0; }
bool CommonSolverUmfpack::solve(Matrix *mat, cplx *res) { printf("UMFPACK solver - cplx\n"); CSCMatrix *Acsc = NULL; if (CooMatrix *mcoo = dynamic_cast<CooMatrix*>(mat)) Acsc = new CSCMatrix(mcoo); else if (CSCMatrix *mcsc = dynamic_cast<CSCMatrix*>(mat)) Acsc = mcsc; else if (CSRMatrix *mcsr = dynamic_cast<CSRMatrix*>(mat)) Acsc = new CSCMatrix(mcsr); else _error("Matrix type not supported."); int nnz = Acsc->get_nnz(); int size = Acsc->get_size(); // complex components double *Axr = new double[nnz]; double *Axi = new double[nnz]; cplx *Ax = Acsc->get_Ax_cplx(); for (int i = 0; i < nnz; i++) { Axr[i] = Ax[i].real(); Axi[i] = Ax[i].imag(); } umfpack_zi_defaults(control_array); /* symbolic analysis */ void *symbolic, *numeric; int status_symbolic = umfpack_zi_symbolic(size, size, Acsc->get_Ap(), Acsc->get_Ai(), NULL, NULL, &symbolic, control_array, info_array); print_status(status_symbolic); /* LU factorization */ int status_numeric = umfpack_zi_numeric(Acsc->get_Ap(), Acsc->get_Ai(), Axr, Axi, symbolic, &numeric, control_array, info_array); print_status(status_numeric); umfpack_zi_free_symbolic(&symbolic); double *xr = new double[size]; double *xi = new double[size]; double *resr = new double[size]; double *resi = new double[size]; for (int i = 0; i < size; i++) { resr[i] = res[i].real(); resi[i] = res[i].imag(); } /* solve system */ int status_solve = umfpack_zi_solve(UMFPACK_A, Acsc->get_Ap(), Acsc->get_Ai(), Axr, Axi, xr, xi, resr, resi, numeric, control_array, info_array); print_status(status_solve); umfpack_zi_free_numeric(&numeric); delete[] resr; delete[] resi; delete[] Axr; delete[] Axi; if (symbolic) umfpack_di_free_symbolic(&symbolic); if (numeric) umfpack_di_free_numeric(&numeric); for (int i = 0; i < Acsc->get_size(); i++) res[i] = cplx(xr[i], xi[i]); delete[] xr; delete[] xi; if (!dynamic_cast<CSCMatrix*>(mat)) delete Acsc; }
bool CommonSolverUmfpack::solve(Matrix *mat, double *res) { printf("UMFPACK solver\n"); CSCMatrix *Acsc = NULL; if (CooMatrix *mcoo = dynamic_cast<CooMatrix*>(mat)) Acsc = new CSCMatrix(mcoo); else if (CSCMatrix *mcsc = dynamic_cast<CSCMatrix*>(mat)) Acsc = mcsc; else if (CSRMatrix *mcsr = dynamic_cast<CSRMatrix*>(mat)) Acsc = new CSCMatrix(mcsr); else _error("Matrix type not supported."); int nnz = Acsc->get_nnz(); int size = Acsc->get_size(); // solve umfpack_di_defaults(control_array); /* symbolic analysis */ void *symbolic, *numeric; int status_symbolic = umfpack_di_symbolic(size, size, Acsc->get_Ap(), Acsc->get_Ai(), NULL, &symbolic, control_array, info_array); print_status(status_symbolic); /* LU factorization */ int status_numeric = umfpack_di_numeric(Acsc->get_Ap(), Acsc->get_Ai(), Acsc->get_Ax(), symbolic, &numeric, control_array, info_array); print_status(status_numeric); umfpack_di_free_symbolic(&symbolic); double *x = new double[size]; /* solve system */ int status_solve = umfpack_di_solve(UMFPACK_A, Acsc->get_Ap(), Acsc->get_Ai(), Acsc->get_Ax(), x, res, numeric, control_array, info_array); print_status(status_solve); umfpack_di_free_numeric(&numeric); if (symbolic) umfpack_di_free_symbolic(&symbolic); if (numeric) umfpack_di_free_numeric(&numeric); memcpy(res, x, size*sizeof(double)); delete[] x; if (!dynamic_cast<CSCMatrix*>(mat)) delete Acsc; }