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

#ifndef BLOCK_H
#define BLOCK_H

#include "general.h"
#include "matrix.h"
#include "alloc.h"
#include "varalloc.h"

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


class BlockNode
{
  public:

    Num  *D, *DInv;
    static StaticAllocator<BlockNode> alloc;

  public:

    BlockNode() { D=0; DInv=0; }

    void reset(int nComp);
    void setTranspose(int nComp);

    void Add(Vector<Num*>& Ap);
    void Mult (Num* lhs, const Num* rhs, int nComp) const;
    void TMult(Num* lhs, const Num* rhs, int nComp) const;
    void Div  (Num* lhs, const Num* rhs, int nComp) const;

    void getD(Vector<Num>& data, int nComp) const;

    Num& operator()(int comp1, int comp2, int nComp) 
    					   { return D[nComp*(comp1-1)+comp2]; }
    void Invert(Matrix<Num>& AM, Matrix<Num>& AMInv);

    virtual void setDataSpace   (FixedSizeAllocator& dataAlloc, int nComp);
    virtual void removeDataSpace(FixedSizeAllocator& dataAlloc);
};
//-------------------------------------------------------------------------


class NeighbourBlock
{
  public:

    NeighbourBlock* next;
    int 	    block;
    Num* 	    L;
    static StaticAllocator<NeighbourBlock> alloc;

  public:

    NeighbourBlock() { block=0; L=0; next=0; }
    void reset(int nComp);

    virtual void LAdd(Vector<Num*>& Ap);
    virtual void UAdd(Vector<Num*>& Ap) { LAdd(Ap); }
    virtual void getL(Vector<Num>& data, int nComp) const;
    virtual void getU(Vector<Num>& data, int nComp) const;

    virtual void LMult (Num* lhs, const Num* rhs, int nComp) const;
    virtual void UMult (Num* lhs, const Num* rhs, int nComp) const;
    virtual void LTMult(Num* lhs, const Num* rhs, int nComp) const;
    virtual void UTMult(Num* lhs, const Num* rhs, int nComp) const;

    virtual Num& operator()(int comp1, int comp2, int nComp);
    virtual Num& operator()(int comp1, int comp2, int nComp, Bool transpose);

    virtual void setDataSpace   (FixedSizeAllocator& dataAlloc, int nComp);
    virtual void removeDataSpace(FixedSizeAllocator& dataAlloc);
};
//-------------------------------------------------------------------------


class AsymNeighbourBlock : public NeighbourBlock
{
  public:

    Num* U;
    static StaticAllocator<AsymNeighbourBlock> alloc;

  public:

    AsymNeighbourBlock() { U = 0; }
    void reset(int nComp);

    virtual void UAdd(Vector<Num*>& Ap);
    virtual void getU(Vector<Num>& data, int nComp) const;

    virtual void UMult(Num* lhs, const Num* rhs, int nComp) const;
    virtual void UTMult(Num* lhs, const Num* rhs, int nComp) const;

    Num& operator()(int comp1, int comp2, int nComp, Bool transpose);

    virtual void setDataSpace   (FixedSizeAllocator& dataAlloc, int nComp);
    virtual void removeDataSpace(FixedSizeAllocator& dataAlloc);
};

#endif
