121 lines
4.2 KiB
C
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>
|