Exercises_MarkusSchmidt/sheet7/jacobi.template/jacsolve.h
Markus Schmidt 4c92446409 Sheet 7
2026-01-06 14:05:44 +01:00

154 lines
4.9 KiB
C++

#ifndef JACSOLVE_FILE
#define JACSOLVE_FILE
#include "geom.h"
#include "getmatrix.h"
#include <vector>
/**
* 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<double> const &f, std::vector<double> &u);
/**
* 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.
*
* In each smoothing step: @f$ \widehat{u} := u + \omega D^{-1}\left({f-K*u}\right) @f$
*
* @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.
* @param[in,out] r auxiliary local vector.
* @param[in] nsmooth number of smoothing steps.
* @param[in] omega relaxation parameter.
* @param[in] zero initial solution @p u is assumed to be zero.
*/
void JacobiSmoother(Matrix const &SK, std::vector<double> const &f, std::vector<double> &u,
std::vector<double> & r, int nsmooth=1, double const omega=1.0, bool zero=false);
/**
* @brief Simple diagonale preconditioning.
*
* The residuum @p r scaled by the inverse diagonal of matríx @p SK results in the correction @p w.
*
* @f$ w := \omega D^{-1}*r @f$
*
* @param[in] SK matrix
* @param[in] r distributed local vector storing the residuum
* @param[out] w accumulated local vector storing the correction.
* @param[in] omega relaxation parameter.
*/
void DiagPrecond(Matrix const &SK, std::vector<double> const &r, std::vector<double> &w,
double const omega=1.0);
/**
* @brief The Multigrid hierarchy including meshes, vectors and matrices, prolongations is stored.
*/
class Multigrid
{
public:
/**
* Generates the mesh hierachy with @p nlevel meshes starting from coarse mesh @p cmesg .
*
* The refined meshes are generated by edge bisection.
* All memory is allocated but stiffness matrices are yet not calculated
*
* @param[in] cmesh initial coarse mesh
* @param[in] nlevel number of meshes in hierarchy, including the initial coarse mesh
*
*/
Multigrid(Mesh const& cmesh, int nlevel);
Multigrid(Multigrid const&) = delete;
Multigrid& operator=(Multigrid const&) = delete;
~Multigrid();
/**
* @return Number of meshes in hierarchy.
*/
size_t Nlevels() const
{return _meshes.size(); }
/**
* @return Number of Unknowns.
*/
int Ndofs() const
{return _meshes[Nlevels()-1].Nnodes(); }
/**
* @return Meshes number @p lev .
*/
Mesh const& GetMesh(int lev) const
{ return _meshes[lev]; }
/**
* @return Solution vector at level @p lev .
*/
std::vector<double> const& GetSolution(int lev) const
{ return _u.at(lev); }
/**
* Calculates PDE matrices for all levels.
*/
void DefineOperators();
/**
* Calculates PDE matrix for level @p lev.
*
* @param[in] lev level in hierachy
*/
void DefineOperator(size_t lev);
/**
* Solves the system of equations at level @p lev via Jacobi iterations
*
* @param[in] lev level in hierachy
*/
void JacobiSolve(size_t lev);
/**
* Peformes one multigrid step at level @p lev .
*
* @param[in] lev level in hierachy
* @param[in] pre_smooth number of pre/post-smoothing sweeps
* @param[in] bzero start with zero-vector as solution
* @param[in] nu defines the multigrid cycle (1/2 = V/W)
*/
void MG_Step(size_t lev, int pre_smooth=1, bool const bzero=false, int nu=1);
/**
* Solves the system of equations at finest level via multigrid
*
* @param[in] pre_smooth number of pre/post-smoothing sweeps
* @param[in] eps stopping criteria (relative error)
* @param[in] nu defines the multigrid cycle (1/2 = V/W)
*/
void MG_Solve(int pre_smooth=1, double eps=1e-6, int nu=1);
private:
gMesh_Hierarchy _meshes; //!< mesh hierarchy from coarse (level 0) to fine.
std::vector<FEM_Matrix> _SK; //!< Sparse matrix on each level.
std::vector<std::vector<double>> _u; //!< Solution vector on each level.
std::vector<std::vector<double>> _f; //!< Right hand side vector on each level.
std::vector<std::vector<double>> _d; //!< Defect vector on each level.
std::vector<std::vector<double>> _w; //!< Correction vector on each level.
std::vector<BisectIntDirichlet> _Pc2f; //!< Interpolation to level from next coarser level.
};
#endif