function [A,B,EdgesOfElements,PECInd,Dof,r]=EigenModeMatrixAssembly...
    (Nodes,Elements,Domain,lam0,epsilonr,mur)
%Description:Assembling matrices of finite element method for mode analysis

%Gauss quadrature points
[xt,yt,pt,IntegralOrder]=Get2DGuassPoints(2);

%Processsing mesh
el2no=Elements';
n1=el2no([1 1 2],:);
n2=el2no([2 3 3],:);
el_ed2no_array=[n1(:) n2(:)];
[Edges,~,EdgesOfElements]=unique(el_ed2no_array,'rows');
NbrEdges=length(Edges);
NbrNodes=length(Nodes);
NbrElement=max(size(Elements));

%PEC Boundary conditions
NumEdges=zeros(NbrEdges,1);
for i=1:length(EdgesOfElements)
    temp=EdgesOfElements(i);
    NumEdges(temp)=NumEdges(temp)+1;
end
PECEdge=find(NumEdges==1);
PECEdges=Edges(PECEdge,:);
PECNode=[PECEdges(:,1);PECEdges(:,2)];
PECNode=unique(PECNode);
PECNode=sort(PECNode);
PECInd=[PECNode;PECEdge+NbrNodes];

%variable initialization
k0=2*pi/lam0;
Dof=NbrEdges+NbrNodes;
NbrNonZero=NbrElement*9;
NumA=0;
Ai=zeros(NbrNonZero,1);
Aj=zeros(NbrNonZero,1);
Av=complex(zeros(NbrNonZero,1));
NumB=0;
Bi=zeros(NbrNonZero*4,1);
Bj=zeros(NbrNonZero*4,1);
Bv=complex(zeros(NbrNonZero*4,1));

%Loop over meshes
for n=1:NbrElement
    %coordinate of nodes
    x=zeros(3,1);y=zeros(3,1);l=zeros(3,1);
    x(1)=Nodes(Elements(n,1),1);y(1)=Nodes(Elements(n,1),2);
    x(2)=Nodes(Elements(n,2),1);y(2)=Nodes(Elements(n,2),2);
    x(3)=Nodes(Elements(n,3),1);y(3)=Nodes(Elements(n,3),2);
    l(1)=sqrt((x(1)-x(2))*(x(1)-x(2))+(y(1)-y(2))*(y(1)-y(2)));
    l(2)=sqrt((x(1)-x(3))*(x(1)-x(3))+(y(1)-y(3))*(y(1)-y(3)));
    l(3)=sqrt((x(3)-x(2))*(x(3)-x(2))+(y(3)-y(2))*(y(3)-y(2)));
    
    %Jac matrics
    Jac=zeros(3,3);
    Jac(1,1)=x(2)-x(1);Jac(1,2)=y(2)-y(1);
    Jac(2,1)=x(3)-x(1);Jac(2,2)=y(3)-y(1);Jac(3,3)=1;
    InvJac=inv(Jac);
    DetJac=abs(det(Jac));
    TJac=Jac'/det(Jac);
    
    %basis functions
    Et=zeros(3,3,IntegralOrder);curlEt=zeros(3,3,IntegralOrder);
    Ez=zeros(3,3,IntegralOrder);gradEz=zeros(3,3,IntegralOrder);
    temp=zeros(3,1);
    for i=1:IntegralOrder
        for j=1:3
            [temp(1),temp(2)]=BF_Et(j,xt(i),yt(i));temp(3)=0;
            Et(j,:,i)=InvJac*temp*l(j);
            temp(3)=BF_curlEt(j,xt(i),yt(i));temp(1)=0;temp(2)=0;
            curlEt(j,:,i)=TJac*temp*l(j);
            temp(3)=BF_Ez(j,xt(i),yt(i));temp(1)=0;temp(2)=0;
            Ez(j,:,i)=temp;
            [temp(1),temp(2)]=BF_gradEz(j,xt(i),yt(i));temp(3)=0;
            gradEz(j,:,i)=InvJac*temp;
        end
    end
    
    %material
    domain=Domain(n);
    mu=mur(domain);
    epsilon=epsilonr(domain);
    
    %Submatrix
    St=zeros(3,3);Tte=zeros(3,3);
    Sz=zeros(3,3);Tz=zeros(3,3);
    G=zeros(3,3);Ttu=zeros(3,3);
    for i=1:3
        for j=1:3
            for k=1:IntegralOrder
                St(i,j)=St(i,j)+pt(k)*DetJac/mu*dot(curlEt(i,:,k),curlEt(j,:,k));
                Tte(i,j)=Tte(i,j)+pt(k)*DetJac*k0*k0*epsilon*dot(Et(i,:,k),Et(j,:,k));
                Sz(i,j)=Sz(i,j)+pt(k)*DetJac/mu*dot(gradEz(i,:,k),gradEz(j,:,k));
                Tz(i,j)=Tz(i,j)+pt(k)*DetJac*k0*k0*epsilon*dot(Ez(i,:,k),Ez(j,:,k));
                G(i,j)=G(i,j)+pt(k)*DetJac/mu*dot(Et(i,:,k),gradEz(j,:,k));
                Ttu(i,j)=Ttu(i,j)+pt(k)*DetJac/mu*dot(Et(i,:,k),Et(j,:,k));
            end
        end
    end
    Gt=G';
    
    for i=1:3
        for j=1:3
            MappingIndexSi=Elements(n,i);
            MappingIndexSj=Elements(n,j);
            MappingIndexVi=EdgesOfElements((n-1)*3+i)+NbrNodes;
            MappingIndexVj=EdgesOfElements((n-1)*3+j)+NbrNodes;
            
            NumA=NumA+1;
            Ai(NumA)=MappingIndexVi;
            Aj(NumA)=MappingIndexVj;
            Av(NumA)=St(i,j)-Tte(i,j);
            
            NumB=NumB+1;
            Bi(NumB)=MappingIndexVi;
            Bj(NumB)=MappingIndexVj;
            Bv(NumB)=Ttu(i,j);
            
            NumB=NumB+1;
            Bi(NumB)=MappingIndexSi;
            Bj(NumB)=MappingIndexSj;
            Bv(NumB)=Sz(i,j)-Tz(i,j);
            
            NumB=NumB+1;
            Bi(NumB)=MappingIndexVi;
            Bj(NumB)=MappingIndexSj;
            Bv(NumB)=G(i,j);
            
            NumB=NumB+1;
            Bi(NumB)=MappingIndexSi;
            Bj(NumB)=MappingIndexVj;
            Bv(NumB)=Gt(i,j);
        end
    end
end

%Assembling matrices
A = sparse(Ai,Aj,Av);
B = sparse(Bi,Bj,Bv);

%Processing PEC
Free_ind=1:Dof;
Free_ind(PECInd)=[];
A=A(Free_ind,Free_ind);
B=B(Free_ind,Free_ind);

%Matrix reordering
r=symrcm(B);
B=B(r,r);
A=A(r,r);

end