// 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 __lap_assembler_hpp__
#define __lap_assembler_hpp__

#include "CommonTemplateTypes.hpp"
#include "Mesh.hpp"
#include "ExactSolution.hpp"
#include "ElementIterator.hpp"

typedef CommonTemplateTypes::GlobalMatrixType GlobalMatrixType;
typedef CommonTemplateTypes::LocalMatrixType  LocalMatrixType;
typedef CommonTemplateTypes::GlobalVectorType GlobalVectorType;
typedef CommonTemplateTypes::LocalVectorType  LocalVectorType;
typedef CommonTemplateTypes::FEManagerType FEManagerType;
typedef CommonTemplateTypes::MeshType MeshType;
typedef CommonTemplateTypes::LiftingOperatorType LiftingOperatorType;

struct LapAssembler
{
  static void assemble_volume_contribution(const MeshType& mesh,
                                           GlobalMatrixType& matrix, 
                                           GlobalVectorType& pRhs, 
                                           FEManagerType& FEManager);
  
  static void assemble_elem_contribution(const MeshType& mesh,
                                         GlobalMatrixType& matrix, 
                                         GlobalVectorType& pRhs, 
                                         FEManagerType& FEManager,
					 const std::pair<int,int>& elemRange);
  
  static void assemble_boundary_face_contribution(const MeshType& mesh,
                                                  GlobalMatrixType& matrix, 
                                                  GlobalVectorType& pRhs, 
     		         		          FEManagerType& FEManager);

  static void assemble_internal_face_contribution(const MeshType& mesh,
                                                  GlobalMatrixType& matrix, 
                                                  GlobalVectorType& pRhs, 
				                  FEManagerType& FEManager);
};

#endif
