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

#ifndef ELEMENTS3_H
#define ELEMENTS3_H

#include "elementsA.h"

typedef Real (shapeFct3)(Real x, Real y, Real z);

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


class Tetra : public StdElement
{

  public:

    Tetra(Material* material);
    virtual ~Tetra() { }

    virtual int SpaceDim()     const { return 3; }

    virtual int NoOfPoints()   const { return 4; }
    virtual int NoOfNodes()    const { return 4; }

    virtual int NodesOnPoint() const { return 1; }
    virtual int NodesOnEdge()  const { return 0; }
    virtual int InnerNodes ()  const { return 0; }

    virtual int NoOfEdges() const { return 6; }
    virtual int NoOfFaces() const { return 4; }

    virtual Real SF(int node, const Vector<Real>& unitCoord) const 
	{ return (*sf[node])(unitCoord[1], unitCoord[2], unitCoord[3]); }
    virtual Real dSF(int node, int deriv, const Vector<Real>& unitCoord) const 
	{ return (*dsf[node][deriv])(unitCoord[1], unitCoord[2], unitCoord[3]); }

    virtual void assembleConstEllip (const PATCH& patch, Matrix<Real>& A,
				     const Jacobian& Jac, 
				     const Matrix<Bool>* pattern) const
	    { assembleConstEllip3(patch, A, Jac, pattern); } 

    virtual void assembleConstConvec(const PATCH& patch, Matrix<Real>& A, 
				     const Jacobian& Jac, 
				     const Matrix<Bool>* pattern) const
	    { assembleConstConvec3(patch, A, Jac, pattern); }

  protected:

    Tetra() : StdElement() { }

    virtual void basicInit();
    virtual void compConstantMatrices();

    virtual void getLocalFaceNodes(int edNo, Vector<int>& nodes) const;

    shapeFct3*  sf[1+4],
    	      *dsf[1+4][1+3]; // (*dsf[i][k])(...): dsf(node i)/dx(k)
};
//-------------------------------------------------------------------------


class HQuadTetra : public Tetra
{

  public:

    HQuadTetra(Material* material);

    virtual int NoOfNodes()    const { return 10; }
    virtual int NodesOnEdge()  const { return  1; }

    virtual Real SF(int node, const Vector<Real>& unitCoord) const 
      { return (*HQsf[node])(unitCoord[1], unitCoord[2], unitCoord[3]); }

    virtual Real dSF(int node, int deriv, const Vector<Real>& unitCoord) const 
      { return (*dHQsf[node][deriv])(unitCoord[1], unitCoord[2], unitCoord[3]); }


  protected:

    HQuadTetra() : Tetra() { }

    virtual void basicInit();
    virtual void setPatterns();

    virtual void getLocalFaceNodes(int edNo, Vector<int>& nodes) const;

    shapeFct3*  HQsf[1+10],
    	      *dHQsf[1+10][1+3]; // (*dsf[i][k])(...): dsf(node i)/dx(k)

};
//-------------------------------------------------------------------------

		
// --		   Quadratic Lagrangian Tetra:


class LQuadTetra : public HQuadTetra
{
    
  public:
    
    LQuadTetra(Material* material);
  
    virtual Real SF(int node, const Vector<Real>& unitCoord) const 
      { return (*LQsf[node])(unitCoord[1], unitCoord[2], unitCoord[3]); }

    virtual Real dSF(int node, int deriv, const Vector<Real>& unitCoord) const 
      { return (*dLQsf[node][deriv])(unitCoord[1], unitCoord[2], unitCoord[3]); }

  protected:
    
    virtual void basicInit();

    shapeFct3*  LQsf[1+14],
    	      *dLQsf[1+14][1+3]; // (*dsf[i][k])(...): dsf(node i)/dx(k)

};
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------


class HQuadTetraFast : public HQuadTetra
{

  public:

    HQuadTetraFast(Material* material0) : HQuadTetra(material0) { }

    virtual Bool assembleEllip(const PATCH& patch, Matrix<Real>& A,
			       const Jacobian& Jac, 
			       const Matrix<Bool>* pattern) const;
};
//-------------------------------------------------------------------------


class EFTetraFast : public Tetra
{
  public:

    virtual int NoOfNodes()    const { return 14; }

    EFTetraFast(Material* material);

    virtual Bool assembleEllip(const PATCH& patch, Matrix<Real>& A,
			       const Jacobian& Jac, 
			       const Matrix<Bool>* pattern) const;

    virtual Real SF(int node, const Vector<Real>& unitCoord) const 
      { return (*Csf[node])(unitCoord[1], unitCoord[2], unitCoord[3]); }

    virtual Real dSF(int node, int deriv, const Vector<Real>& unitCoord) const 
      { return (*dCsf[node][deriv])(unitCoord[1], unitCoord[2], unitCoord[3]); }

  protected:

    virtual void basicInit();
    virtual void getLocalFaceNodes(int edNo, Vector<int>& nodes) const;

    shapeFct3*  Csf[1+14],
    	      *dCsf[1+14][1+3]; // (*dsf[i][k])(...): dsf(node i)/dx(k)
};

#endif
