function C = ConvectionMatrix(X,T,referenceElement,velo)
% C = ConvectionMatrix(X,T,referenceElement,velo)
%
% X,T: nodal coordinates and connectivities for velocity
% referenceElement: reference element properties (quadrature, shape functions...)
% velo: velocity field

elem = referenceElement.elemV;
ngaus = referenceElement.ngaus;
wgp = referenceElement.GaussWeights;
N = referenceElement.N;
Nxi = referenceElement.Nxi;
Neta = referenceElement.Neta;
ngeom = referenceElement.ngeom; 

% Number of elements and number of nodes in each element
[nElem,nenV] = size(T);

% Number of nodes
nPt_V = size(X,1);
if elem == 11
    nPt_V = nPt_V + nElem; 
end

% Number of degrees of freedom 
nedofV = 2*nenV;
ndofV = 2*nPt_V;

C = zeros(ndofV,ndofV);

% Loop on elements
for ielem = 1:nElem
    % Global number of the nodes in element ielem
    Te = T(ielem,:);
    % Coordinates of the nodes in element ielem
    Xe = X(Te(1:ngeom),:);
    % Velocities for the element
    Ve = velo(Te(1:ngeom),:);
    % Degrees of freedom in element ielem
    Te_dof = reshape([2*Te-1; 2*Te],1,nedofV);
    
    % Element matrices
    Ce = EleMatC(Xe,ngeom,nedofV,ngaus,wgp,N,Nxi,Neta,Ve);
    
    % Assemble the element matrices
    C(Te_dof, Te_dof) = C(Te_dof, Te_dof) + Ce;
end



function Ce = EleMatC(Xe,ngeom,nedofV,ngaus,wgp,N,Nxi,Neta,Ve)
% Ce = EleMatC(Xe,ngeom,nedofV,ngaus,wgp,N,Nxi,Neta,NP)

Ce = zeros(nedofV,nedofV);
% Loop on Gauss points 
for ig = 1:ngaus
    N_ig    = N(ig,:);
    Nxi_ig  = Nxi(ig,:);
    Neta_ig = Neta(ig,:);
    Jacob = [
        Nxi_ig(1:ngeom)*(Xe(:,1))	Nxi_ig(1:ngeom)*(Xe(:,2))
        Neta_ig(1:ngeom)*(Xe(:,1))	Neta_ig(1:ngeom)*(Xe(:,2))
        ];
    dvolu = wgp(ig)*det(Jacob);
    res = Jacob\[Nxi_ig;Neta_ig];
    nx = res(1,:);
    ny = res(2,:);
    
	% Gradient
    Ngp = [reshape([1;0]*N_ig,1,nedofV); reshape([0;1]*N_ig,1,nedofV)];
    Nx = [reshape([1;0]*nx,1,nedofV); reshape([0;1]*nx,1,nedofV)];
    Ny = [reshape([1;0]*ny,1,nedofV); reshape([0;1]*ny,1,nedofV)];

    v_ig = N_ig*Ve;
    
    Ce = Ce + Ngp'*(v_ig(1)*Nx+v_ig(2)*Ny)*dvolu; 
end
