# solver_abtb(2rheolef) [debian man page]

```solver_abtb(2rheolef)						    rheolef-6.1 					     solver_abtb(2rheolef)

NAME
solver_abtb -- direct or iterative solver iterface for mixed linear systems

SYNOPSIS
solver_abtb stokes	  (a,b,mp);
solver_abtb elasticity (a,b,c,mp);

DESCRIPTION
The solver_abtb class provides direct or iterative algorithms for some mixed problem:

[ A  B^T ] [ u ]	  [ Mf ]
[        ] [   ]	= [    ]
[ B  -C  ] [ p ]	  [ Mg ]

where  A  is  symmetric	positive definite and C is symmetric positive.	By default, iterative algorithms are considered for tridimensional
problems and direct methods otherwise.  Such mixed linear problems appears for instance with the discretization of Stokes problems.  The  C
matrix  can  be	zero  and  then the corresponding argument can be omitted when invoking the constructor.  Non-zero C matrix appears for of
Stokes problems with stabilized P1-P1 element, or for nearly incompressible elasticity problems.

DIRECT ALGORITHM
When the kernel of B^T is not reduced to zero, then the pressure p is defined up to a constant and the system is singular. In the  case	of
iterative  methods,  this is not a problem.  But when using direct method, the system is then completed to impose a constraint on the pres-
sure term and the whole matrix is factored one time for all.

ITERATIVE ALGORITHM
The preconditionned conjugate gradient algorithm is used, where the mp matrix is used as preconditionner. See see mixed_solver(4).

EXAMPLES
See the user's manual for practical examples for the nearly incompressible elasticity, the Stokes and the Navier-Stokes problems.

IMPLEMENTATION
template <class T, class M = rheo_default_memory_model>
class solver_abtb_basic {
public:

// typedefs:

typedef typename csr<T,M>::size_type size_type;

// allocators:

solver_abtb_basic ();
solver_abtb_basic (const csr<T,M>& a, const csr<T,M>& b, const csr<T,M>& mp,
const solver_option_type& opt = solver_option_type());
solver_abtb_basic (const csr<T,M>& a, const csr<T,M>& b, const csr<T,M>& c, const csr<T,M>& mp,
const solver_option_type& opt = solver_option_type());

// accessors:

void solve (const vec<T,M>& f, const vec<T,M>& g, vec<T,M>& u, vec<T,M>& p) const;

protected:
// internal
void init();
// data:
mutable solver_option_type _opt;
csr<T,M>	   _a;
csr<T,M>	   _b;
csr<T,M>	   _c;
csr<T,M>	   _mp;
solver_basic<T,M> _sA;
solver_basic<T,M> _sa;
solver_basic<T,M> _smp;
bool		   _need_constraint;
};
typedef solver_abtb_basic<Float,rheo_default_memory_model> solver_abtb;

SEE ALSO
mixed_solver(4)

rheolef-6.1							    rheolef-6.1 					     solver_abtb(2rheolef)```

## Check Out this Related Man Page

```csr(2rheolef)							    rheolef-6.1 						     csr(2rheolef)

NAME
csr - compressed sparse row matrix (rheolef-6.1)

SYNOPSYS
Distributed compressed sparse matrix container stored row by row.

DESCRIPTION
Sparse matrix are compressed by rows. In distributed environment, the distribution follows the row distributor (see distributor(2)).

ALGEBRA
Adding or substracting two matrices writes a+b and a-b, respectively, and multiplying a matrix by a scalar writes lambda*x.  Thus, any lin-
ear combination of sparse matrices is available.

Matrix-vector product writes a*x where x is a vector (see vec(2)).

LIMITATIONS
Some basic linear algebra is still under development: a.trans_mult(x) matrix transpose  vector  product,  trans(a)  matrix  transpose,  a*b
matrix product.

IMPLEMENTATION
template<class T>
class csr<T,sequential> : public smart_pointer<csr_seq_rep<T> > {
public:

// typedefs:

typedef csr_seq_rep<T>		     rep;
typedef smart_pointer<rep>		     base;
typedef typename rep::memory_type	     memory_type;
typedef typename rep::size_type	     size_type;
typedef typename rep::element_type	     element_type;
typedef typename rep::iterator	     iterator;
typedef typename rep::const_iterator      const_iterator;
typedef typename rep::data_iterator	     data_iterator;
typedef typename rep::const_data_iterator const_data_iterator;

// allocators/deallocators:

csr() : base(new_macro(rep())) {}
explicit csr(const asr<T,sequential>& a) : base(new_macro(rep(a.data()))) {}
void resize (size_type loc_nrow1 = 0, size_type loc_ncol1 = 0, size_type loc_nnz1 = 0)
{ base::data().resize(loc_nrow1, loc_ncol1, loc_nnz1); }
void resize (const distributor& row_ownership, const distributor& col_ownership, size_type nnz1 = 0)
{ base::data().resize(row_ownership, col_ownership, nnz1); }

// allocators from initializer list (c++ 2011):

#ifdef _RHEOLEF_HAVE_STD_INITIALIZER_LIST
csr (const std::initializer_list<csr_concat_value<T,sequential> >& init_list);
csr (const std::initializer_list<csr_concat_line<T,sequential> >&  init_list);
#endif // _RHEOLEF_HAVE_STD_INITIALIZER_LIST

// accessors:

// global sizes
const distributor& row_ownership() const { return base::data().row_ownership(); }
const distributor& col_ownership() const { return base::data().col_ownership(); }
size_type dis_nrow () const		    { return row_ownership().dis_size(); }
size_type dis_ncol () const		    { return col_ownership().dis_size(); }
size_type dis_nnz () const		    { return base::data().nnz(); }
bool is_symmetric() const		    { return base::data().is_symmetric(); }
void set_symmetry (bool is_symm)	    { base::data().set_symmetry(is_symm); }
size_type pattern_dimension() const	    { return base::data().pattern_dimension(); }
void set_pattern_dimension(size_type dim){ base::data().set_pattern_dimension(dim); }

// local sizes
size_type nrow () const		    { return base::data().nrow(); }
size_type ncol () const		    { return base::data().ncol(); }
size_type nnz () const		    { return base::data().nnz(); }

// range on local memory
size_type row_first_index () const	    { return base::data().row_first_index(); }
size_type row_last_index () const	    { return base::data().row_last_index(); }
size_type col_first_index () const	    { return base::data().col_first_index(); }
size_type col_last_index () const	    { return base::data().col_last_index(); }

const_iterator begin() const 	    { return base::data().begin(); }
const_iterator end()   const 	    { return base::data().end(); }
iterator begin_nonconst()		    { return base::data().begin(); }
iterator end_nonconst()		    { return base::data().end(); }

// accessors, only for distributed (for interface compatibility)
size_type ext_nnz() const		    { return 0; }
const_iterator ext_begin() const	    { return const_iterator(); }
const_iterator ext_end()   const	    { return const_iterator(); }
size_type jext2dis_j (size_type jext) const { return 0; }

// algebra:

// y := a*x
void mult (const vec<element_type,sequential>& x, vec<element_type,sequential>& y) const {
base::data().mult (x,y);
}
vec<element_type,sequential> operator* (const vec<element_type,sequential>& x) const {
vec<element_type,sequential> y (row_ownership(), element_type());
mult (x, y);
return y;
}
void trans_mult (const vec<element_type,sequential>& x, vec<element_type,sequential>& y) const {
base::data().trans_mult (x,y);
}
vec<element_type,sequential> trans_mult (const vec<element_type,sequential>& x) const {
vec<element_type,sequential> y (col_ownership(), element_type());
trans_mult (x, y);
return y;
}
// a+b, a-b
csr<T,sequential> operator+ (const csr<T,sequential>& b) const;
csr<T,sequential> operator- (const csr<T,sequential>& b) const;

// lambda*a
csr<T,sequential>& operator*= (const T& lambda) {
base::data().operator*= (lambda);
return *this;
}
// output:

void dump (const std::string& name) const { base::data().dump(name); }
};
// lambda*a
template<class T>
inline
csr<T,sequential>
operator* (const T& lambda, const csr<T,sequential>& a)
{
csr<T,sequential> b = a;
b.operator*= (lambda);
return b;
}
// -a
template<class T>
inline
csr<T,sequential>
operator- (const csr<T,sequential>& a)
{
return T(-1)*a;
}
// trans(a)
template<class T>
inline
csr<T,sequential>
trans (const csr<T,sequential>& a)
{
csr<T,sequential> b;
a.data().build_transpose (b.data());
return b;
}

IMPLEMENTATION
template<class T>
class csr<T,distributed> : public smart_pointer<csr_mpi_rep<T> > {
public:

// typedefs:

typedef csr_mpi_rep<T>		     rep;
typedef smart_pointer<rep>		     base;
typedef typename rep::memory_type	     memory_type;
typedef typename rep::size_type	     size_type;
typedef typename rep::element_type	     element_type;
typedef typename rep::iterator	     iterator;
typedef typename rep::const_iterator      const_iterator;
typedef typename rep::data_iterator	     data_iterator;
typedef typename rep::const_data_iterator const_data_iterator;

// allocators/deallocators:

csr() : base(new_macro(rep())) {}
explicit csr(const asr<T,memory_type>& a) : base(new_macro(rep(a.data()))) {}
void resize (const distributor& row_ownership, const distributor& col_ownership, size_type nnz1 = 0)
{ base::data().resize(row_ownership, col_ownership, nnz1); }

// allocators from initializer list (c++ 2011):

#ifdef _RHEOLEF_HAVE_STD_INITIALIZER_LIST
csr (const std::initializer_list<csr_concat_value<T,distributed> >& init_list);
csr (const std::initializer_list<csr_concat_line<T,distributed> >&  init_list);
#endif // _RHEOLEF_HAVE_STD_INITIALIZER_LIST

// accessors:

// global sizes
const distributor& row_ownership() const { return base::data().row_ownership(); }
const distributor& col_ownership() const { return base::data().col_ownership(); }
size_type dis_nrow () const		    { return row_ownership().dis_size(); }
size_type dis_ncol () const		    { return col_ownership().dis_size(); }
size_type dis_nnz () const		    { return base::data().dis_nnz(); }
bool is_symmetric() const		    { return base::data().is_symmetric(); }
void set_symmetry (bool is_symm)	    { base::data().set_symmetry(is_symm); }
size_type pattern_dimension() const	    { return base::data().pattern_dimension(); }
void set_pattern_dimension(size_type dim){ base::data().set_pattern_dimension(dim); }

// local sizes
size_type nrow () const		    { return base::data().nrow(); }
size_type ncol () const		    { return base::data().ncol(); }
size_type nnz () const		    { return base::data().nnz(); }

// range on local memory
size_type row_first_index () const	    { return base::data().row_first_index(); }
size_type row_last_index () const	    { return base::data().row_last_index(); }
size_type col_first_index () const	    { return base::data().col_first_index(); }
size_type col_last_index () const	    { return base::data().col_last_index(); }

const_iterator begin() const 	    { return base::data().begin(); }
const_iterator end()   const 	    { return base::data().end(); }
iterator begin_nonconst()		    { return base::data().begin(); }
iterator end_nonconst()		    { return base::data().end(); }

// accessors, only for distributed
size_type ext_nnz() const		    { return base::data().ext_nnz(); }
const_iterator ext_begin() const	    { return base::data().ext_begin(); }
const_iterator ext_end()   const	    { return base::data().ext_end(); }
size_type jext2dis_j (size_type jext) const { return base::data().jext2dis_j(jext); }

// algebra:

// y := a*x
void mult (const vec<element_type,distributed>& x, vec<element_type,distributed>& y) const {
base::data().mult (x,y);
}
vec<element_type,distributed> operator* (const vec<element_type,distributed>& x) const {
vec<element_type,distributed> y (row_ownership(), element_type());
mult (x, y);
return y;
}
void trans_mult (const vec<element_type,distributed>& x, vec<element_type,distributed>& y) const {
base::data().trans_mult (x,y);
}
vec<element_type,distributed> trans_mult (const vec<element_type,distributed>& x) const {
vec<element_type,distributed> y (col_ownership(), element_type());
trans_mult (x, y);
return y;
}
// a+b, a-b
csr<T,distributed> operator+ (const csr<T,distributed>& b) const;
csr<T,distributed> operator- (const csr<T,distributed>& b) const;

// lambda*a
csr<T,distributed>& operator*= (const T& lambda) {
base::data().operator*= (lambda);
return *this;
}
// output:

void dump (const std::string& name) const { base::data().dump(name); }
};
// lambda*a
template<class T>
inline
csr<T,distributed>
operator* (const T& lambda, const csr<T,distributed>& a)
{
csr<T,distributed> b = a;
b.operator*= (lambda);
return b;
}
// -a
template<class T>
inline
csr<T,distributed>
operator- (const csr<T,distributed>& a)
{
return T(-1)*a;
}
// trans(a)
template<class T>
inline
csr<T,distributed>
trans (const csr<T,distributed>& a)
{
csr<T,distributed> b;
a.data().build_transpose (b.data());
return b;
}

SEE ALSO
distributor(2), vec(2)

rheolef-6.1							    rheolef-6.1 						     csr(2rheolef)```
Man Page