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

#ifndef FAMILYA_H
#define FAMILYA_H

#include "family.h"
#include "matrix.h"
#include "alloc.h"

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


class MCGeneration : public Generation
{
  protected:

    const int nComp;

  public:

    MCGeneration(int noOfNodes, int nComp);
    virtual ~MCGeneration() { }

    virtual MCGeneration* castToMCGeneration() { return this; }

    virtual void extend(int noOfNodes);

    virtual void insertSon(int node, Son* newSon);
    virtual Son* getSon(int node) const;

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

    virtual void rhsToHB(Vector<Num>& r) const;
    virtual void solToNB(Vector<Num>& e) const;
};
//-------------------------------------------------------------------------


class LinEdgeGeneration : public Generation
{
  public:

    Matrix<int>*  fathers;

  public:

    LinEdgeGeneration(int low, int high);
    virtual ~LinEdgeGeneration();

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

    virtual void rhsToHB(Vector<Num>& r) const;
    virtual void solToNB(Vector<Num>& e) const;

    void setFathers(int father1, int father2, int son);

    virtual void print() const;
};
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
/*
   class DefSon : public Son
   {
   public:
   
   int     nodeNo;
   int     father;
   float   weight;
   DefSon* next;
   
   public:
   
   DefSon() { reset(); }
   virtual void reset() { nodeNo=father=0; next=Null; }
   virtual void prolong (const Vector<Num>& el, Vector<Num>& eh) 
   { eh[nodeNo] += weight*el[father]; }
   virtual void restr(const Vector<Num>&  rh, Vector<Num>& rl) 
   { rl[father] += weight*rh[nodeNo]; }
   
   // virtual Son* Next() { return next; }
   };
*/
//-------------------------------------------------------------------------


class PointSon : public Son
{
  public:

    int  father;

    static StaticAllocator<PointSon> alloc;

    void* operator new(size_t /*size*/)  { return alloc.Get(); }
    void  operator delete(void* son) { alloc.Return((PointSon*) son); }

    PointSon() { reset(); }
    ~PointSon() { }

    virtual void reset() { father = 0; }

    virtual int  NoOfFathers() const { return 1; }
    virtual int  getFather(int /*i*/=1) const { return father; }
    virtual Real getWeight(int /*i*/) const { return 1.0; };

    virtual void prolong (const Vector<Num>& el, Num& eh) const 
    							 { eh += el[father]; }
    virtual void restr(Num rh, Vector<Num>& rl) const { rl[father] += rh; }

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

    virtual Son* Next() { return 0; }

    virtual void print() const;
};
//-------------------------------------------------------------------------


class EdgeSon : public Son
{
  public:

    int  father1, father2;
    static StaticAllocator<EdgeSon> alloc;

  public:

    void* operator new(size_t /*size*/)  { return alloc.Get(); }
    void  operator delete(void* son) { alloc.Return((EdgeSon*) son); }

    EdgeSon() { reset(); }
    ~EdgeSon() { }
    virtual void reset() { father1 = father2 = 0; }

    virtual int  NoOfFathers() const { return 2; }
    virtual int  getFather(int i=1) const;
    virtual Real getWeight(int /*i*/)   const { return 0.5; };

    virtual void prolong(const Vector<Num>& el, Num& eh) const
    				{ eh += 0.5*(el[father1]+el[father2]); }

    virtual void restr(Num rh, Vector<Num>& rl) const
    		{ rl[father1] += 0.5*rh;  rl[father2] += 0.5*rh; }
    
    virtual void prolong(const Vector<Num>& el, Vector<Num>& eh, int node, 
			 int nComp)  const;
    virtual void restr(Vector<Num>& rh, Vector<Num>& rl, int node, 
			  int nComp) const;

    virtual Son* Next() { return 0; }

    virtual void print() const;
};


#endif

