#ifndef INCLUDE_NASTSOLVERPOISSON2DSOR_H
#define INCLUDE_NASTSOLVERPOISSON2DSOR_H

//-----------------------------------------------------------------------------
//  NastSolverPoisson2dSOR.h
//-----------------------------------------------------------------------------
//
//  Copyright (C) 1998 Technische Universitaet Muenchen, Germany
//  written by Bernhard Brueck
//
//  This file is part of Nast++
//
//-----------------------------------------------------------------------------
//  Implementationen einer SOR-Loesers fue die Poissongleichung.
//  Die Parameter werden bei der Erzeugung des Objekts angegeben.
//-----------------------------------------------------------------------------
//  Aenderungen:
//

#include "NastConfig.h"
#include "NastDebug.h"
#include "NastSolverPoisson2d.h"
#include "NastArray2d.h"

class CNastStaggeredGrid2d;

class CNastSolverPoisson2dSOR : public CNastSolverPoisson2d
{
public:
    //-------------------------------------------------------------------------
    //                         Konstruktor + Destruktor
    //-------------------------------------------------------------------------

    CNastSolverPoisson2dSOR( int itermax,     // max Iterationsanzahl
        		     double eps,      // fuer die Abbruchbedingung
        		     double omega,
        		     bool   bUseRedBlack = false,
        		     int    nDebug = 0 );  // Parameter fuer SOR

    virtual ~CNastSolverPoisson2dSOR();			            


    //-------------------------------------------------------------------------
    //                            Memberfunktionen
    //-------------------------------------------------------------------------
    virtual void solve( CNastStaggeredGrid2d &gridP, 
        		CNastGrid2d          &gridRhs );

    //-------------------------------------------------------------------------
    //                                  Debug
    //-------------------------------------------------------------------------
    //  debugInfo    gibt Information ueber den Zustand des Objekts aus
    //  assertValid  testet das Objekt auf Integritaet
    //
    virtual void debugDump( CNastDumpContext &dumpContext ) const;
    virtual void assertValid() const;

private:
    // nicht impl.
    CNastSolverPoisson2dSOR( const CNastSolverPoisson2dSOR &other);	            
    const CNastSolverPoisson2dSOR& operator=( const CNastSolverPoisson2dSOR &other );

    //-------------------------------------------------------------------------
    //                            Hilfsfunktionen
    //-------------------------------------------------------------------------
    //
    //  Zugriff auf Werte, die ueber die Lebensdauer des Objekts erhalten bleiben:
    //    eps()                Iteration solange residium < eps
    //    omega()              Relaxationsparameter fuer SOR
    //    itermax()            max. Anzahl der Iteration
    //  
    //  Zugriff auf Werte, die bei jedem Aufruf von solve neu gesetzt werden:
    //    countFluidCells()    Anzahl der Fluidzellen
    //    grid()               liefert Referenz auf das aktuelle Gitter
    //    rhs()                liefert Referenz auf die rechte Seite
    //    getCell(i,j)         liefert Zelle (entspricht ehemaligen Flagfeld)
    //    P(i,j)               direkter Zugriff auf den Druck
    //    rdx2()               1 / (dx * dx)
    //    rdy2()               1 / (dy * dy)
    //    beta2()             -1./ (2.0*(m_rdx2+m_rdy2))
    //    
    //  Berechnungschritte:
    //     resInsideFluid(i,j) Res. in einer inneren Fluidzelle
    //     resBorder(i,j)      Res. in einer Randzelle
    //     residium()          Residium ueber das gesamte Gebiet
    //     relax(i,k)          Relaxation auf einer einzelnen Fluidzelle
    //     relax()             Relaxation auf dem gesamten Gebiet
    //     loop()              Hauptschleife

    void show_residium() const;

    double residium( int i, int j ) const;
    double residium( int i ) const;
    double residium() const;

//    double relax( int i, int j) const;

    double relax_red_black( int i, bool toggleRedBlack ) const;
    double relax_red_black() const;

    void   relax( int i) const;
    double relax() const;

    void   loop();

    CNastGrid2d& rhs() const;
    CNastStaggeredGrid2d& grid() const;

    //-------------------------------------------------------------------------
    //                            Membervariablen
    //-------------------------------------------------------------------------

    //  fuer die Kommunikation innerhalb der Klasse
    double m_rdx2;		// 1 / (dx * dx)
    double m_rdy2;              // 1 / (dy * dy)
    double m_omega;             // Parameter omega fuer die Ueberrelaxation    

    CNastStaggeredGrid2d *m_pGrid;
    CNastGrid2d          *m_pRhs;
    
    int    m_itermax;           // max. Anzahl an Iterationsschritten
    double m_eps;		// fuer die Abbruchbedingung
    bool   m_bUseRedBlack;      // Red-Black oder normal ?
    int    m_nDebug;		// 0 keine Ausgabe, 1 Ausgabe pro solve, 
                                // 2 Ausgabe pro Relaxationsschritt
};
#endif // INCLUDE_NASTSOLVERPOISSON2DSOR_H

