function [M,K,C] = FEM_matrices(X,T,Conv,referenceElement) 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This functions sets up the system to be solved for the transient convection,
% diffusion, reaction equation
%
% Input:
%  X --> nodal coordinates
%  T --> connectivities
%  referenceElement --> data structure containing shape functions, derivatives,
%  gauss points, etc...
%  Conv --> convective velocity
%
% Output:
%  M --> mass matrix
%  K --> stiffness (diffusion) matrix
%  C --> convection matrix
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% reference element information
nen = referenceElement.nen; 
ngaus = referenceElement.ngaus; 
wgp = referenceElement.GaussWeights; 
N = referenceElement.N; 
Nxi = referenceElement.Nxi; 
Neta = referenceElement.Neta; 

% Total number of elements and number of nodes in each element
numel = size(T,1); 
% Total number of nodes
numnp = size(X,1); 

% Allocation 
M = zeros(numnp);
K = zeros(numnp);
C = zeros(numnp);

% Loop on elements
for ielem=1:numel
    % Te: global number of nodes on the current element
    Te = T(ielem,:); 
    % Xe: coordinates of the nodes in Te
    Xe = X(Te,:); 
    % Element Matrix
    Conve = Conv(Te,:);
    [Me,Ke,Ce] = EleMat(Xe,Conve,nen,ngaus,wgp,N,Nxi,Neta);
    % Assembly
    M(Te,Te) = M(Te,Te) + Me; 
    K(Te,Te) = K(Te,Te) + Ke; 
    C(Te,Te) = C(Te,Te) + Ce;
    clear Me Ce Ke
end



function [Me,Ke,Ce] = EleMat(Xe,Conve,nen,ngaus,wgp,N,Nxi,Neta)
%

Me = zeros(nen);
Ke = zeros(nen);
Ce = zeros(nen);

% Loop on Gauss points 
for igaus = 1:ngaus
    N_igaus = N(igaus,:);
    Nxi_igaus = Nxi(igaus,:);
    Neta_igaus = Neta(igaus,:);
    Jacob = [Nxi_igaus*(Xe(:,1))	Nxi_igaus*(Xe(:,2))
             Neta_igaus*(Xe(:,1))	Neta_igaus*(Xe(:,2))];
    dvolu = wgp(igaus)*det(Jacob);
    res = Jacob\[Nxi_igaus;Neta_igaus];
    Nx = res(1,:);
    Ny = res(2,:);
    
    % velocity on the element
    a = N_igaus*Conve; ax = a(1); ay = a(2); 
    
    % elemental matrices
    Me = Me + N_igaus'*N_igaus*dvolu; 
    Ke = Ke + (Nx+Ny)'*(Nx+Ny)*dvolu;
    Ce = Ce + N_igaus'*(ax*Nx+ay*Ny)*dvolu;
end

