//********************************************************************************
//*
//*  C++ finite element method for heat equation
//*  James sandham
//*  15 April 2015
//*
//********************************************************************************

//********************************************************************************
//
// HeatFE is free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License (as published by the Free
// Software Foundation) version 2.1 dated February 1999.
//
//********************************************************************************

#ifndef SHAPE_H
#define SHAPE_H


class Shape
{
  public:
    double N[10];       //shape functions
    double dN[3][10];   //derivaives of shape functions

  private:
    int Type,Npe,nDim;  //element type, nodes per element, dimension

  public: Shape(int typ);   

  virtual void shape(double xi, double et, double ze) = 0;
  virtual void dshape(double xi, double et, double ze) = 0;
};



class Point0D : public Shape
{
  public:
    virtual void shape(double xi, double et, double ze);
    virtual void dshape(double xi, double et, double ze);

  Point0D(int typ) : Shape(typ){}
};



class LineLin1D : public Shape
{
  public:
    virtual void shape(double xi, double et, double ze);
    virtual void dshape(double xi, double et, double ze);

  LineLin1D(int typ) : Shape(typ){}
};



class TriLin2D : public Shape
{
  public:
    virtual void shape(double xi, double et, double ze);
    virtual void dshape(double xi, double et, double ze);

  TriLin2D(int typ) : Shape(typ){}
};



class SqrLin2D : public Shape
{
  public:
    virtual void shape(double xi, double et, double ze);
    virtual void dshape(double xi, double et, double ze);

  SqrLin2D(int typ) : Shape(typ){}
};



class TetLin3D : public Shape
{
  public:
    virtual void shape(double xi, double et, double ze);
    virtual void dshape(double xi, double et, double ze);

  TetLin3D(int typ) : Shape(typ){}
};



class LineQuad1D : public Shape
{
  public:
    virtual void shape(double xi, double et, double ze);
    virtual void dshape(double xi, double et, double ze);

  LineQuad1D(int typ) : Shape(typ){}
};



class TriQuad2D : public Shape
{
  public:
    virtual void shape(double xi, double et, double ze);
    virtual void dshape(double xi, double et, double ze);

  TriQuad2D(int typ) : Shape(typ){}
};



class SqrQuad2D : public Shape
{
  public:
    virtual void shape(double xi, double et, double ze);
    virtual void dshape(double xi, double et, double ze);

  SqrQuad2D(int typ) : Shape(typ){}
};



class TetQuad3D : public Shape
{
  public:
    virtual void shape(double xi, double et, double ze);
    virtual void dshape(double xi, double et, double ze);

  TetQuad3D(int typ) : Shape(typ){}
};



//Factory Class
class ShapeFactory
{
  public:
    static Shape* NewShape(int typ)
    {
      switch(typ)
      {
        case 1:
          return new LineLin1D(typ);
          break;
        case 2:
          return new TriLin2D(typ);
          break;
        case 3:
          return new SqrLin2D(typ);
          break;
        case 4:
          return new TetLin3D(typ);
          break;
        case 8:
          return new LineQuad1D(typ);
          break;
        case 9:
          return new TriQuad2D(typ);
          break;
        case 10:
          return new SqrQuad2D(typ);
          break;
        case 11:
          return new TetQuad3D(typ);
          break;
        case 15:
          return new Point0D(typ);
          break;
        default:
          return NULL;
      }
    }
};

#endif
