// SpaFEDTe, a Template based C++ library for creating 
// Discontinuous Finite Element Spaces,
// Copyright (C) 2012 Lorenzo Alessio Botti

/* This library 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 either */ 
/* version 3.0 of the License, or (at your option) any later version. */

/* This software is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU */
/* Lesser General Public License for more details. */

/* You should have received a copy of the GNU Lesser General Public */
/* License along with this software; if not, a copy of the full */
/* GNU Lesser General Public License can be found at */
/* http://www.gnu.org/licenses/. */

#ifndef __FEManager_face_h__
#define __FEManager_face_h__

#include "CollectiveBasisFunction.hpp"
#include "BasisFunction.hpp"
#include "CollectiveMappingFunction.hpp"
#include "MappingBasisFunction.hpp"
#include "Quadrature.hpp"

template<typename FaceBasisFunctionType, typename FaceMappingFunctionType>
class FEManagerFace
{
public:
  typedef typename FaceBasisFunctionType::ShapeMatrix FaceShapeMatrixType;          
  typedef typename FaceBasisFunctionType::ShapeDerivMatrix FaceShapeDerivMatrixType;
  typedef typename FaceMappingFunctionType::NormalVector NormalVectorType; 
  typedef typename FaceMappingFunctionType::CoordVector CoordVectorType; 
  typedef typename FaceMappingFunctionType::JacVector FaceJacobianVectorType; 
  typedef typename FaceMappingFunctionType::PointVector FaceQpointVectorType;     

  FEManagerFace ()
  {
    ;
  }

  ~FEManagerFace () { }

  const FaceShapeMatrixType& getPartitionFaceElemShapeFunction() const
  {
    return partitionElemBasisFunction.getShapeFunction();
  }
  const FaceShapeMatrixType& getPartitionFaceNeighborShapeFunction() const
  {
    return partitionNeighborBasisFunction.getShapeFunction();
  }
  const FaceShapeMatrixType& getInternalFaceElemShapeFunction() const
  {
    return internalElemBasisFunction.getShapeFunction();
  }
  const FaceShapeMatrixType& getInternalFaceNeighborShapeFunction() const
  {
    return internalNeighborBasisFunction.getShapeFunction();
  }
  const FaceShapeMatrixType& getBoundaryFaceElemShapeFunction() const
  {
    return boundaryBasisFunction.getShapeFunction();
  }
  const FaceShapeDerivMatrixType& getPartitionFaceElemShapeFunctionDeriv() const
  {
    return partitionElemBasisFunction.getShapeFunctionDeriv();
  }
  const FaceShapeDerivMatrixType& getPartitionFaceNeighborShapeFunctionDeriv() const
  {
    return partitionNeighborBasisFunction.getShapeFunctionDeriv();
  }
  const FaceShapeDerivMatrixType& getInternalFaceElemShapeFunctionDeriv() const
  {
    return internalElemBasisFunction.getShapeFunctionDeriv();
  }
  const FaceShapeDerivMatrixType& getInternalFaceNeighborShapeFunctionDeriv() const
  {
    return internalNeighborBasisFunction.getShapeFunctionDeriv();
  }
  const FaceShapeDerivMatrixType& getBoundaryFaceElemShapeFunctionDeriv() const
  {
    return boundaryBasisFunction.getShapeFunctionDeriv();
  }
  const NormalVectorType& getInternalFaceNormalVec() const
  {
    return internalMappingFunction.getNormalVec();
  }
  const NormalVectorType& getPartitionFaceNormalVec() const
  {
    return partitionMappingFunction.getNormalVec();
  }
  const NormalVectorType& getBoundaryFaceNormalVec() const
  {
    return boundaryMappingFunction.getNormalVec();
  }
  const FaceJacobianVectorType& getInternalFaceJacobianWeightVec() const
  {
    return internalMappingFunction.getJacobianXweight();
  }
  const FaceJacobianVectorType& getPartitionFaceJacobianWeightVec() const
  {
    return partitionMappingFunction.getJacobianXweight();
  }
  const FaceJacobianVectorType& getBoundaryFaceJacobianWeightVec() const
  {
    return boundaryMappingFunction.getJacobianXweight();
  }
  const FaceQpointVectorType& getInternalFaceQpointX() const
  {
    return internalMappingFunction.getQpointX();
  }
  const FaceQpointVectorType& getPartitionFaceQpointX() const
  {
    return partitionMappingFunction.getQpointX();
  }
  const FaceQpointVectorType& getBoundaryFaceQpointX() const
  {
    return boundaryMappingFunction.getQpointX();
  }

public:
  // internal faces  
  FaceBasisFunctionType internalElemBasisFunction;
  FaceBasisFunctionType internalNeighborBasisFunction;
  FaceMappingFunctionType internalMappingFunction; 
  // boundary faces 
  FaceBasisFunctionType boundaryBasisFunction;
  FaceMappingFunctionType boundaryMappingFunction; 
  // partition faces 
  FaceBasisFunctionType partitionElemBasisFunction;
  FaceBasisFunctionType partitionNeighborBasisFunction;
  FaceMappingFunctionType partitionMappingFunction; 
  
  Quadrature sideQuadrature;
};

#endif
