From 25ef327985d8ddf78786a816f9d4dbb8adb6aee1 Mon Sep 17 00:00:00 2001 From: "lisa.pizzo" Date: Tue, 16 Dec 2025 11:04:56 +0100 Subject: [PATCH] Added a new parallelized function --- Sheet5/Ex5_Second_Attempt/jacsolve.cpp | 145 +++++++++++++++++++++++++ Sheet5/Ex5_Second_Attempt/jacsolve.h | 18 +++ 2 files changed, 163 insertions(+) create mode 100644 Sheet5/Ex5_Second_Attempt/jacsolve.cpp create mode 100644 Sheet5/Ex5_Second_Attempt/jacsolve.h diff --git a/Sheet5/Ex5_Second_Attempt/jacsolve.cpp b/Sheet5/Ex5_Second_Attempt/jacsolve.cpp new file mode 100644 index 0000000..7aff121 --- /dev/null +++ b/Sheet5/Ex5_Second_Attempt/jacsolve.cpp @@ -0,0 +1,145 @@ +#include "vdop.h" +#include "getmatrix.h" +#include "jacsolve.h" + +#include +#include +#include +#include +#include +using namespace std; + +// ##################################################################### +// const int neigh[], const int color, +// const MPI::Intracomm& icomm, +void JacobiSolve(CRS_Matrix const &SK, vector const &f, vector &u) +{ + const double omega = 1.0; + const int maxiter = 1000; + const double tol = 1e-5, // tolerance + tol2 = tol * tol; // tolerance^2 + + int nrows = SK.Nrows(); // number of rows == number of columns + assert( nrows == static_cast(f.size()) && f.size() == u.size() ); + + cout << endl << " Start Jacobi solver for " << nrows << " d.o.f.s" << endl; + // Choose initial guess + for (int k = 0; k < nrows; ++k) + { + u[k] = 0.0; // u := 0 + } + + vector dd(nrows); // matrix diagonal + vector r(nrows); // residual + vector w(nrows); // correction + + SK.GetDiag(dd); // dd := diag(K) + ////DebugVector(dd);{int ijk; cin >> ijk;} + + // Initial sweep + SK.Defect(r, f, u); // r := f - K*u + + vddiv(w, r, dd); // w := D^{-1}*r + double sigma0 = dscapr(w, r); // s0 := + + // Iteration sweeps + int iter = 0; + double sigma = sigma0; + while ( sigma > tol2 * sigma0 && maxiter > iter) + { + ++iter; + vdaxpy(u, u, omega, w ); // u := u + om*w + SK.Defect(r, f, u); // r := f - K*u + vddiv(w, r, dd); // w := D^{-1}*r + sigma = dscapr(w, r); // s0 := +// cout << "Iteration " << iter << " : " << sqrt(sigma/sigma0) << endl; + } + cout << "aver. Jacobi rate : " << exp(log(sqrt(sigma / sigma0)) / iter) << " (" << iter << " iter)" << endl; + cout << "final error: " << sqrt(sigma / sigma0) << " (rel) " << sqrt(sigma) << " (abs)\n"; + + return; +} + + +void JacobiSolve_omp(CRS_Matrix const &SK, + vector const &f, + vector &u) +{ + const double omega = 1.0; + const int maxiter = 1000; + const double tol = 1e-5; + const double tol2 = tol * tol; + + const int nrows = SK.Nrows(); + assert(nrows == static_cast(f.size()) && f.size() == u.size()); + + cout << "\n Start Jacobi solver (OpenMP) for " + << nrows << " d.o.f.s\n"; + + // -------------------------------------------------- + // Initial guess + // -------------------------------------------------- + #pragma omp parallel for + for (int i = 0; i < nrows; ++i) + u[i] = 0.0; + + vector dd(nrows); + vector r(nrows); + vector w(nrows); + + SK.GetDiag(dd); + + // r = f - K*u + SK.Defect(r, f, u); + + // w = D^{-1} r + #pragma omp parallel for + for (int i = 0; i < nrows; ++i) + w[i] = r[i] / dd[i]; + + // sigma0 = + double sigma0 = 0.0; + #pragma omp parallel for reduction(+:sigma0) + for (int i = 0; i < nrows; ++i) + sigma0 += w[i] * r[i]; + + double sigma = sigma0; + int iter = 0; + + // -------------------------------------------------- + // Jacobi iteration + // -------------------------------------------------- + while (sigma > tol2 * sigma0 && iter < maxiter) + { + ++iter; + + // u = u + omega * w + #pragma omp parallel for + for (int i = 0; i < nrows; ++i) + u[i] += omega * w[i]; + + // r = f - K*u + SK.Defect(r, f, u); + + // w = D^{-1} r + #pragma omp parallel for + for (int i = 0; i < nrows; ++i) + w[i] = r[i] / dd[i]; + + // sigma = + sigma = 0.0; + #pragma omp parallel for reduction(+:sigma) + for (int i = 0; i < nrows; ++i) + sigma += w[i] * r[i]; + } + + cout << "aver. Jacobi rate : " + << exp(log(sqrt(sigma / sigma0)) / iter) + << " (" << iter << " iter)\n"; + + cout << "final error: " + << sqrt(sigma / sigma0) << " (rel) " + << sqrt(sigma) << " (abs)\n"; +} + + diff --git a/Sheet5/Ex5_Second_Attempt/jacsolve.h b/Sheet5/Ex5_Second_Attempt/jacsolve.h new file mode 100644 index 0000000..3487aa0 --- /dev/null +++ b/Sheet5/Ex5_Second_Attempt/jacsolve.h @@ -0,0 +1,18 @@ +#ifndef JACSOLVE_FILE +#define JACSOLVE_FILE +#include "getmatrix.h" +#include + + +/** + * Solves linear system of equations K @p u = @p f via the Jacobi iteration. + * We use a distributed symmetric CSR matrix @p SK and initial guess of the + * solution is set to 0. + * @param[in] SK CSR matrix + * @param[in] f distributed local vector storing the right hand side + * @param[out] u accumulated local vector storing the solution. +*/ +void JacobiSolve(CRS_Matrix const &SK, std::vector const &f, std::vector &u); +void JacobiSolve_omp(CRS_Matrix const &SK, std::vector const &f, std::vector &u); + +#endif