function L = CreLaplace(X,IEN,elem) 
% L = CreLaplace(X,IEN,elem) 
% This funciont creates the matrix L obtained by discretyzing 
% the laplacian of an scalar function (pressure) in 2D
% 
% Input:    X:    matrix of nodal coordinates
%           IEN:  connectivities
%           elem: type of element (0: quadrilateral, 1:triangle) 
%


% Number of nodes and degrees of freedom
[numel,nen] = size(IEN); 
if elem == 1 & nen == 4
    numnp = size(X,1) + numel;
else
    numnp = size(X,1);     
end
nunk  = numnp; 

% Number of Gauss points in each element (ngaus) and
% numner of points describing geometry (ngeom)
if elem == 0
    if nen == 4
        ngaus = 4; ngeom = 4;
    elseif nen == 9
        ngaus = 9; ngeom=9;
    end
else   
    if nen == 3
        ngaus = 4; ngeom = 3;
    elseif nen == 6 
        ngaus = 7; ngeom = 6;
    elseif nen == 4
        ngaus = 7; ngeom = 3;
    end
end

% Numerical quadrature
[pospg,wpg] = Quadrature(elem,ngaus);
[N,Nxi,Neta] = ShapeFunc(elem,nen,pospg);

% Allocation
L  = sparse(zeros(nunk,nunk)) ;

% Loop on elements
for ielem = 1:numel 
    Te = IEN(ielem,:);
    Xe = X(IEN(ielem,1:ngeom),:); 
    Le = zeros(nen,nen);
    % Loop on Gauss points
    for igaus = 1:ngaus
        % N_igaus    = N(igaus,:);  
        Nxi_igaus  = Nxi(igaus,:);   
        Neta_igaus = Neta(igaus,:);
        
        Jacob = [Nxi_igaus(1:ngeom)*(Xe(:,1))	Nxi_igaus(1:ngeom)*(Xe(:,2))   
                 Neta_igaus(1:ngeom)*(Xe(:,1))	Neta_igaus(1:ngeom)*(Xe(:,2))];
        
        dvolu = wpg(igaus)*det(Jacob); 
        
        res = Jacob\[Nxi_igaus;Neta_igaus]; 
        Nx = res(1,:); Ny = res(2,:);

        Le = Le + (Nx'*Nx+Ny'*Ny)*dvolu; 
    end
    % Assembly
    L(Te,Te) = L(Te,Te) + Le; 
    clear Le; 
end 
L = sparse(L);