/* $Id: precondnl.h,v 1.3 1996/11/20 09:57:30 roitzsch Exp $ */

#ifndef PRECONDNL_H
#define PRECONDNL_H

#include "precondmg.h"
#include "numerics.h"

#include "stack.h"

class SystemMatrix;
class SparseMatrix;
class FamilyTree;

class NonLinearity;

//-------------------------------------------------------------------------


class NonLinearSGGS : public Preconditioner 
{
  protected:

    NonLinearity& 	nonLinearity;
    const Vector<Num>*  sol;

  public: 

    NonLinearSGGS(NonLinearity& nonLinearity0);
    virtual ~NonLinearSGGS() { }
    virtual precondMode mode() { return singleGrid; }

    virtual void initialize(SystemMatrix* A, Vector<Num>& x, Vector<Num>& b);
    virtual void close     (SystemMatrix* A, Vector<Num>& x, Vector<Num>& b);
    virtual void invert(Vector<Num>& s, SystemMatrix* A, Vector<Num>& r);
};
//-------------------------------------------------------------------------


class NonLinearMLGS : public MMGPreconditioner 
{
  protected:

    NonLinearity& 	 nonLinearity;
    Vector<Num>          eMG, ADiag0;
    Stack<Vector<Real>*> lowDefObstacle, uppDefObstacle;

    const Vector<Num>*   sol;
    Bool		 topLevelSmoothing; 

  public: 

    NonLinearMLGS(NonLinearity& nonLinearity0);
    virtual ~NonLinearMLGS();

    virtual precondMode mode() { return multiLevel; }
    virtual void initialize(SystemMatrix* A, Vector<Num>& x, Vector<Num>& b);
    virtual void close     (SystemMatrix* A, Vector<Num>& x, Vector<Num>& b);

    virtual void update(SystemMatrix* A, FamilyTree* familyTree,
			DirichletBCs* dirichletBCs);

    virtual void invert(Vector<Num>& s, SystemMatrix* A, Vector<Num>& r);

  protected:

    virtual void NonLinGSStep(Vector<Num>& s, SystemMatrix* A, Vector<Num>& r);

    virtual void setCritical  (int /*node*/) { }
    virtual void setUnCritical(int /*node*/) { }
    virtual Bool isCritical   (int /*node*/, int /*level*/) { return False; }

    virtual void restrictObstacles(int highLevel);

    virtual void preSmooth(int level, Vector<Num>& e, SystemMatrix& A, 
			   Vector<Num>& r);
    virtual void postSmooth(int level, Vector<Num>& e, SystemMatrix& A, 
			    Vector<Num>& r);

    virtual void restr(Vector<Num>& rh, Vector<Num>& rl, int level);
    virtual void prolong (Vector<Num>& el, Vector<Num>& eh, int level);

    friend class RK2;
};
//-------------------------------------------------------------------------


class TrcNonLinearMLGS : public NonLinearMLGS
{
  protected:

    Stack<Vector<SBool>*>  critical;	

  public: 

    TrcNonLinearMLGS(NonLinearity& nonLinearity0);
    virtual ~TrcNonLinearMLGS();

    virtual void update(SystemMatrix* A, FamilyTree* familyTree,
			DirichletBCs* dirichletBCs);
    virtual void initialize(SystemMatrix* A, Vector<Num>& x, Vector<Num>& b);

  protected:

    virtual void setCritical  (int node);
    virtual void setUnCritical(int node);
    virtual Bool isCritical   (int node, int level);

    virtual void restr(Vector<Num>& rh, Vector<Num>& rl, int level);
    virtual void prolong (Vector<Num>& el, Vector<Num>& eh, int level);

    friend class RK2;
};


#endif


