// ============================================================================ // == == // == AMDiS - Adaptive multidimensional simulations == // == == // ============================================================================ // == == // == crystal growth group == // == == // == Stiftung caesar == // == Ludwig-Erhard-Allee 2 == // == 53175 Bonn == // == germany == // == == // ============================================================================ // == == // == http://www.caesar.de/cg/AMDiS == // == == // ============================================================================ /** \file Preconditioner.h */ #ifndef AMDIS_PRECONDITIONER_H #define AMDIS_PRECONDITIONER_H #include #include "DOFVector.h" #include "MatrixVector.h" #include "SystemVector.h" #include namespace AMDiS { // ============================================================================ // ===== class Preconditioner ================================================= // ============================================================================ /** * \ingroup Solver * * \brief * Pure virtual base class for all preconditioners. * A Preconditioner is used by an OEMSolver before solving the linear system to * reduce the number of needed iterations. */ template class Preconditioner { public: /** \brief * Destructor. */ virtual ~Preconditioner() {}; /** \brief * Initialisation of the preconditioner */ virtual void init() = 0; /** \brief * Precondition function which should be implemented. */ virtual void precon(Vector *x) = 0; /** \brief * Frees needed memory. */ virtual void exit() = 0; }; // ============================================================================ // ===== class PreconditionerScal ============================================= // ============================================================================ /** * \ingroup Solver * * Base class for DOFVector preconditioners. */ class PreconditionerScal : public Preconditioner > { public: /** \brife * Constructor. */ PreconditionerScal(int numSystems = 1, int r = 0) : matrix(numSystems), bound(NULL), row(r) { TEST_EXIT(r < numSystems)("r must be smaller than numSystems\n"); matrix.set(NULL); }; /** \brief * Sets \ref matrix. */ inline void setMatrix(DOFMatrix **m, int system = 0) { TEST_EXIT(system < matrix.getSize())("invalid system number\n"); matrix[system] = m; }; /** \brief * Sets \ref bound. */ inline void setBound(DOFVector *b) { bound = b; }; protected: /** \brief * Matrix used for preconditioning. */ Vector matrix; /** \brief * Boundary vector */ DOFVector *bound; /** \brief * Row of the component in vector valued problems. */ int row; }; // ============================================================================ // ===== class PreconditionerScalStd ========================================== // ============================================================================ /** * \ingroup Solver * * Base class for DOFVector preconditioners. */ class PreconditionerScalStd : public Preconditioner< ::std::vector > { public: /** \brife * Constructor. */ PreconditionerScalStd() {}; /** \brief * Sets \ref matrix. */ inline void setMatrix(::std::vector< ::std::vector > *m) { matrix = m; }; protected: /** \brief * Matrix used for preconditioning. */ ::std::vector< ::std::vector > *matrix; }; // ============================================================================ // ===== PreconditionerScalCreator ============================================ // ============================================================================ /** * \ingroup Solver * * \brief * Interface for creators of concrete scalar preconditioners. */ class PreconditionerScalCreator : public CreatorInterface { public: PreconditionerScalCreator() : size(1), row(0) {}; virtual ~PreconditionerScalCreator() {}; /** \brief * Sets \ref problem */ void setSizeAndRow(int size_, int row_) { size = size_; row = row_; }; /** \brief * Sets \ref problem */ void setName(::std::string name) { name_ = name; }; protected: int size; int row; ::std::string name_; }; // ============================================================================ // ===== class PreconditionerVec ============================================== // ============================================================================ /** * \ingroup Solver * * \brief * Base class for vector valued preconditioners. */ class PreconditionerVec : public Preconditioner { public: MEMORY_MANAGED(PreconditionerVec); /** \brief * Constructor. */ PreconditionerVec(int numSystems) : scalPrecons(numSystems) { scalPrecons.set(NULL); }; /** \brief * Destructor. */ virtual ~PreconditionerVec() {}; /** \brief * Initialisation of the preconditioner */ virtual void init() { int i; int size = scalPrecons.getSize(); #ifdef _OPENMP #pragma omp parallel for num_threads(size) #endif for (i = 0; i < size; i++) { scalPrecons[i]->init(); } }; /** \brief * Preconditioning method */ virtual void precon(SystemVector *x) { int i; int size = scalPrecons.getSize(); #ifdef _OPENMP #pragma omp parallel for num_threads(size) #endif for (i = 0; i < size; i++) { scalPrecons[i]->precon(x->getDOFVector(i)); } }; /** \brief * Frees needed memory. */ virtual void exit() { int size = scalPrecons.getSize(); for (int i = 0; i < size; i++) { scalPrecons[i]->exit(); } }; /** \brief * Sets scalar preconditioner for system i. */ inline void setScalarPrecon(int i, PreconditionerScal *p) { scalPrecons[i] = p; }; /** \brief * Gets i-th scalar preconditioner. */ inline PreconditionerScal *getScalarPrecon(int i) { return scalPrecons[i]; }; protected: /** \brief * Scalar Preconditioners. */ Vector scalPrecons; }; } #endif // AMDIS_PRECONDITIONER_H