/* $Id: int.h,v 1.1.1.1 1996/10/02 10:35:50 roitzsch Exp $ */

#ifndef INT_H
#define INT_H

#include "general.h"
#include "stack.h"

class PATCH;
class MESH;
class Element;

class LinSystem;
class SystemMatrix;
class Preconditioner;
class FamilyTree;
class Generation;

class DirichletBCs;
class FEPlot;
class Timer;

class NodeCoordinates;

class TrueSolution;
//-------------------------------------------------------------------------


class Interface
{
  protected: 

    // -- 	objects supplied by problem:

    MESH*		mesh;
    const Element*	element;
    DirichletBCs*	dirichletBCs;

    LinSystem* 		Ab;
    Preconditioner* 	precond;


    // -- 	  own interface objects:

    FamilyTree*		familyTree;		// contains grid hierarchy
    SystemMatrix* 	A;

    Stack<int>		noOfNodes, pointNodes;

    const int		spaceDim, nComp;
    Bool		timeUpdate, accTime;
    Real 		accTimeUpdate;

    static FEPlot*     	  fePlot;
    Real		  plotSize;
    Bool		  plotKeep;
    static Stack<FEPlot*> FEPlotStack;


  public:

    Interface(MESH* mesh, const Element* element, DirichletBCs* dirichletBCs,
	      LinSystem* Ab, Preconditioner* precond, int spaceDim, int nComp=1);
    virtual ~Interface();

    int Dim()           const { return noOfNodes.Top(); }
    int NoOfBaseNodes() const { return noOfNodes.Top()/nComp; }
    int MaxDepth()  const;

    virtual int SpaceDim() const { return spaceDim; }

    virtual void getGlobalNodes(const PATCH* t, Vector<int>& globalNodes)const=0;

    virtual void updateLevel0(Vector<Num>& u) 	= 0;
    virtual void refine(Vector<Num>& u) 	= 0;

    virtual void updateDirichletBCs(Real time) const = 0;
    virtual void updatePrecond();

    virtual void getNodeCoordinates(NodeCoordinates& nc) const;


    // --		transient problems: 

    void transportSolution(const Vector<Num>& uPrev, Vector<Num>& uPrevTau,
			   const MESH* prevMesh) const;
			   

    // --		hierarchical basis transforms etc.


    virtual void setHighOrderNodes(int* edNode);    // for DLY error estimator
    virtual void setHBGeneration(Generation& gen);  // for RK2

    virtual void solToNB(Vector<Num>& u);  // P:      solution to nodal basis
    virtual void rhsToNB(Vector<Num>& b);  // P**T:   rhs. to nodal basis
    virtual void solToHB(Vector<Num>& u); 
    virtual void rhsToHB(Vector<Num>& b); 


    // --		output routines


    virtual void plot(Vector<Num>& u, int level, const char* fileName,
		      int timeStep = -99);
    virtual void post(Vector<Num>& u, int level, const char* fileName,
		      int timeStep = -99);
    virtual void autoPost(Vector<Num>& u, int level, const char* fileName,
			  int timeStep = -99);
    virtual void write(Vector<Num>& u, int level, const char* fileName);

    virtual void print();


  protected:

    Interface() : spaceDim(0), nComp(0) { }		// dummy for MI

    virtual void setNodeNumbers() = 0;
    virtual void interpolateSolution(Vector<Num>& u) const;
    		

    // --	     multi-grid and -level operations:

    virtual void updateMGFamilyTree();
    virtual void getGlobalMLNodes(const PATCH* t, Vector<int>& globalNodes,
				int depth) const;
    virtual void setMLNodeNumbers(int maxDepth, int maxDepthM1, 
				  int targetDepth);
    virtual void updateMLFamilyTree(int maxDepth, int maxDepthM1);
    virtual void interpolateMLSolution(Vector<Num>& u,
				       int maxDepth, int maxDepthM1) const;


    // --		plot- and info-routines:

    virtual void plotSolution(Vector<Num>& u, FEPlot* fePlot);
    virtual FEPlot* newFEPlot(int plotType, char* caption=0, float size=0.5);

    void setSolutionVector(Vector<Real>& u1, const Vector<Num>& u);
    // void compressPointNodes();
    // void expandPointNodes();

    void keepOrClearPlot(const char* fileName, int step, int timeStep);
    void completePostFileName(char* psFile, int* noPostScript);


    void timeInfo(Timer& timer, Timer& accTimer);
    void notImplemented(const char* name) const;

    friend class TransientProblem;
};

#endif

