// ============================================================================ // == == // == AMDiS - Adaptive multidimensional simulations == // == == // ============================================================================ // == == // == crystal growth group == // == == // == Stiftung caesar == // == Ludwig-Erhard-Allee 2 == // == 53175 Bonn == // == germany == // == == // ============================================================================ // == == // == http://www.caesar.de/cg/AMDiS == // == == // ============================================================================ /** \file OEMSolver.h */ /** * \defgroup Solver Solver module * @{ @} * * \brief * Contains all classes needed for solving linear and non linear equation * systems. */ #ifndef AMDIS_OEM_SOLVER_H #define AMDIS_OEM_SOLVER_H #include "Global.h" #include "AMDiS_fwd.h" #include "Parameters.h" #include "SolverMatrix.h" #include "DOFVector.h" #include "SystemVector.h" #include "DOFMatrix.h" #include "ITL_Preconditioner.h" namespace AMDiS { /** * \ingroup Solver * *\brief * Solver for linear equation systems. */ class OEMSolver { public: typedef DOFMatrix::base_matrix_type matrix_type; typedef DOFMatrix::value_type value_type; /// The constructor reads needed parameters and sets solvers \ref name. OEMSolver(std::string str) : name(str), tolerance(0), relative(0), max_iter(1000), info(0), residual(0), print_cycle(100), leftPrecon(NULL), rightPrecon(NULL) {} /** \brief * */ virtual ~OEMSolver() { if (leftPrecon) delete leftPrecon; if (rightPrecon) delete rightPrecon; } void initParameters() { FUNCNAME("OEMSolver::initParameters()"); GET_PARAMETER(0, name + "->tolerance", "%f", &tolerance); GET_PARAMETER(0, name + "->relative tolerance", "%f", &relative); GET_PARAMETER(0, name + "->max iteration", "%d", &max_iter); GET_PARAMETER(0, name + "->print cycle", "%d", &print_cycle); GET_PARAMETER(0, name + "->info", "%d", &info); } /** Set left Preconditioner * * It is assumed that the solver owns the preconditioner from this call. * That means that the preconditioner is deleted by the solver when not needed. */ void setLeftPrecon(ITL_BasePreconditioner* p) { if (leftPrecon) delete leftPrecon; leftPrecon= p; } /** Set right Preconditioner * * It is assumed that the solver owns the preconditioner from this call. * That means that the preconditioner is deleted by the solver when not needed. */ void setRightPrecon(ITL_BasePreconditioner* p) { if (rightPrecon) delete rightPrecon; rightPrecon= p; } /// Linear System to be solved in the derived class virtual int solveSystem(const DOFMatrix::base_matrix_type& A, mtl::dense_vector& x, const mtl::dense_vector& b) = 0; /// Solve a linear system for a scalar problem. int solveSystem(const SolverMatrix& A, DOFVector& x, DOFVector& b) { mtl::dense_vector xx(x.getUsedSize(), &x[0]), bb(b.getUsedSize(), &b[0]); return solveSystem(A.getMatrix(), xx, bb); } /// Solve a linear system for a vectorial problem. int solveSystem(const SolverMatrix >& A, SystemVector& x, SystemVector& b) { int ns= x.getSize(), // Number of systems. size= x.getUsedSize(); // Size of all DOFVectors // Copy vectors mtl::dense_vector xx(size), bb(size); for (int i = 0, counter = 0; i < ns; i++) { DOFVector::Iterator it(b.getDOFVector(i), USED_DOFS); for (it.reset(); !it.end(); ++it) bb[counter++] = *it; } // Solver on DOFVector for single system int r= solveSystem(A.getMatrix(), xx, bb); for (int i = 0, counter = 0; i < ns; i++) { DOFVector::Iterator it(x.getDOFVector(i), USED_DOFS); for (it.reset(); !it.end(); ++it) *it = xx[counter++]; } return r; } /** \name getting methods * \{ */ /// Returns solvers \ref name. inline const std::string& getName() { return name; } /// Returns \ref tolerance inline double getTolerance() { return tolerance; } /// Returns \ref max_iter inline int getMaxIterations() { return max_iter; } /// Returns \ref residual inline double getResidual() { return residual; } /** \} */ /** \name setting methods * \{ */ /// Sets \ref tolerance inline void setTolerance(double tol) { tolerance = tol; } /// Sets \ref relative inline void setRelative(bool rel) { relative = rel; } /// Sets \ref max_iter inline void setMaxIterations(int i) { max_iter = i; } /// Sets \ref info inline void setInfo(int i) { info = i; } /** \} */ protected: /// solvers name. std::string name; /// Solver tolerance |r|. Set in OEMSolver's constructor. double tolerance; /// Relative solver tolerance |r|/|r0|. Set in OEMSolver's constructor. double relative; /// maximal number of iterations. Set in OEMSolver's constructor. int max_iter; /// info level during solving the system. Set in OEMSolver's constructor. int info; /// current residual. double residual; /// Print cycle, after how many iterations the residuum norm is logged. int print_cycle; ITL_BasePreconditioner *leftPrecon; ITL_BasePreconditioner *rightPrecon; }; /** * \ingroup Solver * * \brief * Interface for creators of concrete OEMSolvers. */ class OEMSolverCreator : public CreatorInterface { public: virtual ~OEMSolverCreator() {} /// Sets \ref problem void setName(std::string str) { name = str; } protected: /** \brief * Pointer to the problem the solver will belong to. Needed as parameter * when constructing an OEMSolver */ std::string name; }; } #include "ITL_Solver.h" #endif // AMDIS_OEM_SOLVER_H