/* $Id: materials.h,v 1.3 1996/11/19 09:55:33 bzferdma Exp $ */

#ifndef MATERIALS_H
#define MATERIALS_H

#include "general.h"

#include "kvector.h"
#include "matrix.h"

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


class Material 
{
  protected:
    enum materialType       { undefinedMatType, isotropic, anisotropic };

    const int 	  spaceDim;			
    materialType  matType;

  public:

    Material(int spaceDim);
    virtual ~Material() { }

    enum Term { elliptic, source, mass, convection, parabolic, neumann, 
		cauchy, undefinedTerm };

    // matType may be isotropic or anisotropic

    Bool isIsotropic()   { return matType==isotropic;}
    Bool isAnisotropic() { return matType==anisotropic;}

    // --	    inform, if term is present:

    virtual Bool EllipticTerm  (int /*type*/) { return False; }
    virtual Bool SourceTerm    (int /*type*/) { return False; }
    virtual Bool MassTerm      (int /*type*/) { return False; }
    virtual Bool PTerm         (int /*type*/) { return False; }
    virtual Bool ConvectionTerm(int /*type*/) { return False; }


    // --   inform, if coefficient is constant; default: true

    virtual Bool constEllipticTerm  (int /*type*/) { return True; }
    virtual Bool constSourceTerm    (int /*type*/) { return True; }
    virtual Bool constMassTerm      (int /*type*/) { return True; }
    virtual Bool constPTerm         (int /*type*/) { return True; }
    virtual Bool constConvectionTerm(int /*type*/) { return True; }
    virtual Bool constCauchyTerm    (int /*type*/) { return True; }
    virtual Bool constNeumannTerm   (int /*type*/) { return True; }


    // -- 	inform, if Neumann/Cauchy-BC on patch:

    virtual Bool isCauchy (Bool flag, int /*type*/, int /*comp*/=1) { return flag; }
    virtual Bool isNeumann(Bool flag, int /*type*/, int /*comp*/=1) { return flag; }


    // -- 	     return material/BC-values:

    // In derived class: Redefine setMaterialType() if E is overloaded
    virtual void setMaterialType();
    virtual Real E	 (int type, Vector<Real>* x=0, int i=1, int j=1);
    virtual Real M	 (int type, Vector<Real>* x=0, int i=1, int j=1);
    virtual Real P	 (int type, Vector<Real>* x=0, int i=1, int j=1);
    virtual Real C	 (int type, int index, Vector<Real>* x=0);
    virtual Real S       (int type, Vector<Real>* x=0, Real time=0.0);
    virtual Real Neumann (int type, Vector<Real>* x=0, Real time=0.0);
    virtual Real Inner   (int type, Vector<Real>* x=0, Real time=0.0);
    virtual Real Cauchy  (int type, Vector<Real>* x=0, Real time=0.0);

    // -- return exakt Solution
    virtual Num trueSolInPoint(const Vector<Real>& x, const Real time);
    virtual Bool trueSolKnown()   { return False; }

  protected:

    void doubleID(int classA);
    void unknownID(int classA);

    void notImplemented();
};


#endif
