function [sol_str] = vortex(X,T,referenceElement,velo)
% compute vorticity and strength of vortex
%
% X,T: nodal coordinates and connectivities for velocity
% referenceElement: reference element properties (quadrature, shape functions...)


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);

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

K = zeros(ndofV,ndofV);
f = zeros(ndofV,1);
s = zeros(ndofV,1);

% 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 at the nodes in element ielem
    veloe = velo(Te(1:ngeom),:);
    
    % Element matrices
    [Ke,fe,se] = EleMatVortex(Xe,ngeom,nedofV,ngaus,wgp,N,Nxi,Neta,veloe);
    
    % Assemble the element matrices
    K(Te, Te) = K(Te, Te) + Ke;
    f(Te) = f(Te) + fe;
    s(Te) = s(Te) + se;
end

x1 = 0;  x2 = 1; 
y1 = 0;  y2 = 1; 
tol = 1e-6; 
nodesX1 = find(abs(X(:,1)-x1) < tol & abs(X(:,2)-y1) > tol & abs(X(:,2)-y2) > tol);
nodesX2 = find(abs(X(:,1)-x2) < tol & abs(X(:,2)-y1) > tol & abs(X(:,2)-y2) > tol); 
nodesY1 = find(abs(X(:,2)-y1) < tol); 
nodesY2 = find(abs(X(:,2)-y2) < tol);
nodesDir = unique([nodesX1; nodesX2; nodesY1; nodesY2]);
C = [nodesDir, zeros(size(nodesDir))]; % Homogeneous BC
nDir = size(C,1); 
nPt = size(X,1); 
ADir = zeros(nDir,nPt);
ADir(:,C(:,1)) = eye(nDir); 
bDir = C(:,2);
 
Atot = [K   ADir'
     ADir   zeros(nDir)];
ftot = [f;bDir];

sol_str = Atot\ftot;

end



function [Ke,fe,se] = EleMatVortex(Xe,ngeom,nedofV,ngaus,wgp,N,Nxi,Neta,veloe)
% [Ke,Ge,fe] = EleMatStokes(Xe,ngeom,nedofV,nedofP,ngaus,wgp,N,Nxi,Neta,NP)

Ke = zeros(nedofV,nedofV);
fe = zeros(nedofV,1);
se = zeros(nedofV,1);

% 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,:);
    vx = veloe(ig,1);
    vy = veloe(ig,2);
    Jacob_v = [
        Nxi_ig(1:ngeom)*(veloe(:,1))	Nxi_ig(1:ngeom)*(veloe(:,2))
        Neta_ig(1:ngeom)*(veloe(:,1))	Neta_ig(1:ngeom)*(veloe(:,2))
        ];
    res_v = Jacob_v\[Nxi_ig;Neta_ig];

    f_igaus = nx(ig)*vy - ny(ig)*vx;
    Ke = Ke + (nx'*nx+ny'*ny)*dvolu; 
    fe = fe + N_ig'*f_igaus*dvolu; 
    se = se + f_igaus';% vorticity
end

end

