CGII/framework/include/cgv/math/sparse_les.h
2018-05-17 15:50:03 +02:00

121 lines
4.2 KiB
C++

#pragma once
#include <vector>
#include <string>
#include <cgv/data/ref_ptr.h>
#include "lib_begin.h"
namespace cgv {
namespace math {
class CGV_API sparse_les;
/// reference counted pointer type for sparse les solver
typedef cgv::data::ref_ptr<sparse_les,true> sparse_les_ptr;
/// capability options for a sparse linear solver
enum SparseLesCaps
{
SLC_SYMMETRIC = 1,
SLC_UNSYMMETRIC = 2,
SLC_NZE_OPTIONAL = 4,
SLC_ALL = 7
};
/// factory class for sparse linear system solvers
class CGV_API sparse_les_factory : public cgv::data::ref_counted
{
public:
/// return the supported capabilities of the solver
virtual SparseLesCaps get_caps() const = 0;
/// return the name of the solver
virtual std::string get_solver_name() const = 0;
//! create an instance of the solver.
/*! The parameters to the creation function are
- n ... the number of unknowns,
- nr_rhs ... the number of right hand sides
- nr_nze ... the estimated number of non zero elements in the
sparse matrix. For solvers with the SLC_NZE_OPTIONAL
cap flag set, one can skip this argument. */
virtual sparse_les_ptr create(int n, int nr_rhs, int nr_nze = -1) = 0;
};
/// reference counted pointer type for sparse les solver factories
typedef cgv::data::ref_ptr<sparse_les_factory,true> sparse_les_factory_ptr;
/** interface for implementations of solvers for sparse linear systems of the form A * x = b with a square matrix A. */
class CGV_API sparse_les : public cgv::data::ref_counted
{
public:
/**@name static interface */
//@{
/// register a factory for a new type of linear equation solver
static void register_solver_factory(sparse_les_factory_ptr sls_fac);
/// return the list of registered solvers
static const std::vector<sparse_les_factory_ptr>& get_solver_factories();
/// check the registered solver types for one with the given name
static sparse_les_ptr create_by_name(const std::string& solver_name, int n, int nr_rhs, int nr_nze = -1);
/// check the registered solver types for one with the given capabilities and create an instance of it
static sparse_les_ptr create_by_cap(SparseLesCaps caps, int n, int nr_rhs, int nr_nze = -1);
//@}
/**@name problem setup */
//@{
/// set entry in row r and column c in the sparse matrix A
virtual void set_mat_entry(int r, int c, double val) = 0;
/// set i-th entry in a single right hand side b
virtual void set_b_entry(int i, double val);
/// set i-th entry in the j-th right hand side
virtual void set_b_entry(int i, int j, double val) = 0;
/// return reference to i-th entry in a single right hand side b
virtual double& ref_b_entry(int i);
/// set i-th entry in j-th right hand side
virtual double& ref_b_entry(int i, int j) = 0;
//@}
/// try to solve system - in case of success analyze residuals if demanded by the optional parameter
virtual bool solve(bool analyze_residual = false) = 0;
/**@name access to solution*/
//@{
/// return the i-th component of a single solution vector
virtual double get_x_entry(int i) const;
/// return the i-th component of the j-th solution vector
virtual double get_x_entry(int i, int j) const = 0;
//@}
};
/// implementation of factory class for sparse linear system solvers
template <class T>
class sparse_les_factory_impl : public sparse_les_factory
{
protected:
std::string solver_name;
SparseLesCaps caps;
public:
sparse_les_factory_impl(const std::string& _solver_name, SparseLesCaps _caps) :
solver_name(_solver_name), caps(_caps) {}
/// return the supported capabilities of the solver
SparseLesCaps get_caps() const { return caps; }
/// return the name of the solver
std::string get_solver_name() const { return solver_name; }
/// create an instance of the solver.
sparse_les_ptr create(int n, int nr_rhs, int nr_nze) {
return sparse_les_ptr(new T(n, nr_rhs, nr_nze));
}
};
/// helper template to register a sparse les solver
template <class T>
struct register_sparse_les_factory
{
register_sparse_les_factory(const std::string& _solver_name, SparseLesCaps _caps) {
sparse_les::register_solver_factory(sparse_les_factory_ptr(
new sparse_les_factory_impl<T>(_solver_name, _caps)));
}
};
}
}
#include <cgv/config/lib_end.h>