#ifndef ALIMINRESSOLVE_H
#define ALIMINRESSOLVE_H
#include <TObject.h>
#include <TVectorD.h>
class AliMatrixSq;
class AliMatrixSparse;
class AliSymBDMatrix;
class AliMinResSolve : public TObject {
public:
enum {kPreconBD=1,kPreconILU0=100,kPreconILU10=kPreconILU0+10,kPreconsTot};
enum {kSolMinRes,kSolFGMRes,kNSolvers};
public:
AliMinResSolve();
AliMinResSolve(const AliMatrixSq *mat, const TVectorD* rhs);
AliMinResSolve(const AliMatrixSq *mat, const double * rhs);
AliMinResSolve(const AliMinResSolve& src);
~AliMinResSolve();
AliMinResSolve& operator=(const AliMinResSolve& rhs);
Bool_t SolveMinRes(Double_t* VecSol,Int_t precon=0,int itnlim=2000,double rtol=1e-12);
Bool_t SolveMinRes(TVectorD &VecSol,Int_t precon=0,int itnlim=2000,double rtol=1e-12);
Bool_t SolveFGMRES(Double_t* VecSol,Int_t precon=0,int itnlim=2000,double rtol=1e-12, int nkrylov=60);
Bool_t SolveFGMRES(TVectorD &VecSol,Int_t precon=0,int itnlim=2000,double rtol=1e-12, int nkrylov=60);
Bool_t InitAuxMinRes();
Bool_t InitAuxFGMRES(int nkrylov);
void ApplyPrecon(const TVectorD& vecRHS, TVectorD& vecOut) const;
void ApplyPrecon(const double* vecRHS, double* vecOut) const;
Int_t BuildPrecon(Int_t val=0);
Int_t GetPrecon() const {return fPrecon;}
void ClearAux();
Int_t BuildPreconBD(Int_t hwidth);
Int_t BuildPreconILUK(Int_t lofM);
Int_t BuildPreconILUKDense(Int_t lofM);
Int_t PreconILUKsymb(Int_t lofM);
Int_t PreconILUKsymbDense(Int_t lofM);
protected:
Int_t fSize;
Int_t fPrecon;
AliMatrixSq* fMatrix;
Double_t* fRHS;
Double_t *fPVecY;
Double_t *fPVecR1;
Double_t *fPVecR2;
Double_t *fPVecV;
Double_t *fPVecW;
Double_t *fPVecW1;
Double_t *fPVecW2;
Double_t **fPvv;
Double_t **fPvz;
Double_t **fPhh;
Double_t *fDiagLU;
AliMatrixSparse *fMatL;
AliMatrixSparse *fMatU;
AliSymBDMatrix *fMatBD;
ClassDef(AliMinResSolve,0)
};
#endif