/* $Id: elementsA.h,v 1.3 1996/10/31 15:23:17 bzferdma Exp $ */

#ifndef ELEMENTSA_H
#define ELEMENTSA_H

#include "elements.h"
#include "array3.h"

class IntegForm;
class Material;

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


class StdElement : public Element
{
  protected:

    Material* material;
	
    StdElement*  edgeElement;
    StdElement*  faceElement;

 
   	// shape functions etc. for numerical integration:

    		// ... for stiffness matrix:

    Matrix<Real>* N;		// shape functions N(intPoint,Node)
    Array3<Real>* dNU;		// derivatives on basic (unit) element
    IntegForm 	* IF;		// numer. integ. form. for stiffness matrix

    		// ... for mass matrix:

    Matrix<Real>*  NMass;	
    IntegForm   *  IFMass;	
    IntegForm   *  IFLumpedMass;	


    // constant matrices and vectors for unit element (c.f. Schwarz):

    Matrix<Real>*  M;		  // constant mass matrix
    //Matrix<Real>*  P;		  // constant mass matrix in parabolic equation

    Vector<Real>*  B;		  // constant source term

    Matrix<Real>  *S1, *S2, *S3, *S4, *S5, *S6;	// partial stiffness matrices
    Matrix<Real>  *C1, *C2, *C3;		// partial convection matrices


    // Temporaries used in several routines
    Vector<int>   *tmp_nodes;
    Matrix<Real>  *tmp_Ell;
    Matrix<Real>  *tmp_dN;
    Vector<Real>  *tmp_u;
    Vector<Real>  *tmp_x;
    Vector<Real>  *tmp_xBnd;
    Vector<Real>  *tmp_matE;

    virtual int NoOfBaseNodes() const { return NoOfNodes(); }

    virtual void basicInit() = 0;
    virtual void setShapeFunctionsAtIPs(int nComp=1);
    virtual void compConstantMatrices() = 0;

    void transformDerivDN(Matrix<Real>& dN, int ip, const Jacobian& Jac) const;  
					         // unit element -> Real elem.

    void checkUnitCoord(const Vector<Real>& unitCoord) const;
    virtual void InfoIntegFormulas(const char* elementName) const;

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


  public:

    StdElement();
    virtual ~StdElement();

    virtual Num valueAt(const Vector<Real>& unitCoord, 
			const Vector<Num>& sol)  const;

    virtual void valueAt(const Vector<Real>& unitCoord, const Vector<Num>& sol,
			 Vector<Num>& uInt, int baseNode, int nComp) const;

    virtual void gradientAt(int ip, const Jacobian& Jac, 
			    const Vector<Num>& sol, Vector<Num>& grad) const;


    virtual Bool assembleEllip(const PATCH& patch, Matrix<Real>& A, 
			       const Jacobian& Jac, 
			       const Matrix<Bool>* pattern) const;
    virtual void assembleConstEllip(const PATCH& patch, Matrix<Real>& A, 
				    const Jacobian& Jac, 
				    const Matrix<Bool>* pattern) const;
    virtual Bool assembleMass(const PATCH& patch, Matrix<Real>& A, 
			      const Jacobian& Jac, 
			      const Matrix<Bool>* pattern) const;
    virtual Bool assembleLumpedMass(const PATCH& patch, Matrix<Real>& A, 
				    const Jacobian& Jac, 
				    const Matrix<Bool>* pattern) const;
    virtual Bool assembleP(const PATCH& patch, Matrix<Real>& A, 
			      const Jacobian& Jac, 
			      const Matrix<Bool>* pattern) const;
    virtual Bool assembleLumpedP(const PATCH& patch, Matrix<Real>& A, 
				    const Jacobian& Jac, 
				    const Matrix<Bool>* pattern) const;

    virtual Bool assembleConvec (const PATCH& patch, Matrix<Real>& A, 
				 const Jacobian& Jac, 
				 const Matrix<Bool>* pattern) const;
    virtual void assembleConstConvec (const PATCH& patch, Matrix<Real>& A, 
				      const Jacobian& Jac, 
				      const Matrix<Bool>* pattern) const;
    virtual Bool assembleSource	(const PATCH& patch, Vector<Real>& b, 
				 const Jacobian& Jac, 
				 const Matrix<Bool>* pattern,
				 Real time=0.0) const;

    virtual Bool assembleNeumannBCs(const PATCH& patch, Vector<Real>& b, 
				    const Matrix<Bool>* pattern, 
				    Real time=0.0) const;
    virtual Bool assembleInnerBCs  (const PATCH& patch, Vector<Real>& b, 
				    const Matrix<Bool>* pattern, 
				    Real time=0.0) const;
    virtual Bool assembleCauchyBCs (const PATCH& patch, Matrix<Real>& A, 
				    Vector<Real>& b, 
				    const Matrix<Bool>* pattern, 
				    Real time=0.0) const;

    virtual Bool assNeumannBCOnBoundary(const PATCH& ed, Vector<int>& nodes, 
					Vector<Real>& b, 
					const Matrix<Bool>* pattern, 
					Real time=0.0) const;
    virtual Bool assBConInnerBoundary(const PATCH& ed, Vector<int>& nodes, 
					Vector<Real>& b, 
					const Matrix<Bool>* pattern, 
					Real time=0.0) const;
    virtual void assCauchyBCOnBoundary(const PATCH& ed, Vector<int>& nodes, 
				       Matrix<Real>& A, Vector<Real>& b, 
				       const Matrix<Bool>* pattern, 
				       Real time=0.0) const;

    virtual void assembleL2Norm(const PATCH& patch, Matrix<Real>& A, 
				const Jacobian& Jac, 
				const Matrix<Bool>* pattern) const;
    virtual void assembleLNorm (const PATCH& patch, Vector<Real>& b, 
				const Jacobian& Jac, 
				const Matrix<Bool>* pattern) const;

    //-------------------------------------------------------------------------
    //-------------------------------------------------------------------------
 
    // -- 		   special 1D - routines:

    virtual void assembleConstEllip1(const PATCH& patch, Matrix<Real>& A, 
				     const Jacobian& Jac, 
				     const Matrix<Bool>* pattern) const;
    virtual void assembleConstConvec1(const PATCH& patch, Matrix<Real>& A, 
				      const Jacobian& Jac, 
				      const Matrix<Bool>* pattern) const;
    virtual Bool assembleNeumannBCs1(const PATCH& patch, Vector<Real>& b, 
				     const Matrix<Bool>* pattern, 
				     Real time=0.0) const;
     virtual Bool assembleCauchyBCs1(const PATCH& patch, Matrix<Real>& A, 
				     Vector<Real>& b, 
				     const Matrix<Bool>* pattern, 
				     Real time=0.0) const;
    //-------------------------------------------------------------------------
 
    // -- 		   special 2D - routines:

    virtual void assembleConstEllip2(const PATCH& patch, Matrix<Real>& A, 
				     const Jacobian& Jac, 
				     const Matrix<Bool>* pattern) const;
    virtual void assembleConstConvec2(const PATCH& patch, Matrix<Real>& A, 
				      const Jacobian& Jac, 
				      const Matrix<Bool>* pattern) const;
    //-------------------------------------------------------------------------
 
    // -- 		   special 3D - routines:

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

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

    // --   	     specimen for multi-component elements:


    virtual Bool MCEllip(const PATCH& patch, Matrix<Real>& A, 
			 const Jacobian& Jac, const Matrix<Bool>* pattern, 
			 int nComp, const Matrix<int>& Node) const;

    virtual Bool MCConvec (const PATCH& patch, Matrix<Real>& A, 
			   const Jacobian& Jac, const Matrix<Bool>* pattern, 
			   int nComp, const Matrix<int>& Node) const;
    
    virtual Bool MCSource(const PATCH& patch, Vector<Real>& b, 
			  const Jacobian& Jac, const Matrix<Bool>* pattern, 
			  int nComp, const Matrix<int>& Node, Real time) const;

    virtual Bool MCMass(const PATCH& patch, Matrix<Real>& A,
			const Jacobian& Jac, const Matrix<Bool>* pattern, 
			int nComp, const Matrix<int>& Node) const;

    virtual Bool MCLumpedMass(const PATCH& patch, Matrix<Real>& A, 
			      const Jacobian& Jac, const Matrix<Bool>* pattern, 
			      int nComp, const Matrix<int>& Node) const;

    virtual Bool MCNeumannBCs(const PATCH& patch, Vector<Real>& b, 
			      const Matrix<Bool>* pattern,
			      int nComp, const Matrix<int>& Node, 
			      Real time) const;
    virtual Bool MCCauchyBCs (const PATCH& patch, Matrix<Real>& A, 
			      Vector<Real>& b, const Matrix<Bool>* pattern,
			      int nComp, const Matrix<int>& Node, 
			      Real time) const;

    virtual void MCL2Norm(const PATCH& patch, Matrix<Real>& A, 
			  const Jacobian& Jac, const Matrix<Bool>* pattern,
			  int nComp, const Matrix<int>& Node) const;
    virtual void MCLNorm (const PATCH& patch, Vector<Real>& b, 
			  const Jacobian& Jac, const Matrix<Bool>* pattern,
			  int nComp, const Matrix<int>& Node) const;

  protected:

    virtual Bool MCNeumannBCOnBoundary(const PATCH& ed, Vector<int>& nodes, 
				       Vector<Real>& b, 
				       const Matrix<Bool>* pattern,
				       int comp, const Matrix<int>& Node, 
				       Real time) const;
    virtual void MCCauchyBCOnBoundary(const PATCH& ed, Vector<int>& nodes, 
				      Matrix<Real>& A, Vector<Real>& b, 
				      const Matrix<Bool>* pattern,
				      int comp, const Matrix<int>& Node, 
				      Real time) const;
  public:
    
    //-------------------------------------------------------------------------
    //-------------------------------------------------------------------------
 
    // -- 		   special 1D - routines:

    virtual void MCConstEllip1(const PATCH& patch, Matrix<Real>& A, 
			       const Jacobian& Jac, 
			       const Matrix<Bool>* pattern,
			       int nComp, const Matrix<int>& Node) const;
    virtual void MCConstConvec1(const PATCH& patch, Matrix<Real>& A, 
				const Jacobian& Jac, 
				const Matrix<Bool>* pattern,
				int nComp, const Matrix<int>& Node) const;
    virtual Bool MCNeumannBCs1(const PATCH& patch, Vector<Real>& b, 
			       const Matrix<Bool>* pattern,
			       int nComp, const Matrix<int>& Node, 
			       Real time=0.0) const;
    virtual Bool MCCauchyBCs1(const PATCH& patch, Matrix<Real>& A, 
			      Vector<Real>& b, const Matrix<Bool>* pattern,
			      int nComp, const Matrix<int>& Node, 
			      Real time=0.0) const;
    //-------------------------------------------------------------------------
 
    // -- 		   special 2D - routines:

    virtual void MCConstEllip2(const PATCH& patch, Matrix<Real>& A, 
			       const Jacobian& Jac, 
			       const Matrix<Bool>* pattern,
			       int nComp, const Matrix<int>& Node) const;
    virtual void MCConstConvec2(const PATCH& patch, Matrix<Real>& A, 
				const Jacobian& Jac, 
				const Matrix<Bool>* pattern,
				int nComp, const Matrix<int>& Node) const;
    //-------------------------------------------------------------------------
 
    // -- 		   special 3D - routines:

    virtual void MCConstEllip3(const PATCH& patch, Matrix<Real>& A, 
			       const Jacobian& Jac, 
			       const Matrix<Bool>* pattern,
			       int nComp, const Matrix<int>& Node) const;
    virtual void MCConstConvec3(const PATCH& patch, Matrix<Real>& A, 
				const Jacobian& Jac, 
				const Matrix<Bool>* pattern,
				int nComp, const Matrix<int>& Node) const;
};

#endif
