So far we have defined an interface in the class LinearSolver and then implemented it for different solvers: UMFPACK, TAUCS, MUMPS and PARDISO. The implementation in solver_*.cpp uses solvers.h but the application code actually needs almost nothing from these files. The word almost means that it is still necessary to instantiate a particular solver class and this will be achieved by means of a static function LinearSolver::create
. Let us consider its definition in solvers.cpp.
First there are declarations of functions make_*()
. These functions have been defined within the solver implementation. Then in the code of the function
LinearSolver* LinearSolver::create(const string &s);
the map between a string and a function is created and is employed to find the right function for the solver specified in the function argument. For example
LinearSolver *mumps = LinearSolver::create("MUMPS");
create a pointer that will be working with the MUMPS solver. This way the application code is completely independent from the solver definitions. Let us imagine that we add a new solver by deriving it from LinearSolver
and programming it in solver_new.cpp. We need to modify LinearSolver::create
indeed to be able to instantiate the new solver but we do not have to recompile the application code. It will be just enough to relink it for example with a new library.
Another feature of solvers.cpp is the use of preprocessor directives that check if macros USEUMFPACK, USETAUCS, USEMUMPS and USEPARDISO are defined. This allows us at compile time to use only part of solvers. Imagine that for a particular application it would be enough only TAUCS and MUMPS. Then
$ cc -DUSETAUCS -DUSEMUMPS -c solvers.cpp
does the trick and the application must be linked with TAUCS and MUMPS only.
Previous
Introduction
Class Matrix
Class SparseMatrix
Sample code in C++ to run TAUCS
Sample code in C++ to run MUMPS
Class LinearSolver
Class UMFPACK
Class TAUCS
Class MUMPS and PARDISO
Next
Sample driver to run a sparse solver
RSS