365 lines
12 KiB
Mathematica
365 lines
12 KiB
Mathematica
|
function [] = FESolveX2D()
|
||
|
% MATLAB based 2-D XFEM Solver
|
||
|
% J. Grogan (2012)
|
||
|
clear all
|
||
|
% Define Mesh
|
||
|
NumX=4;
|
||
|
NumY=1;
|
||
|
delX=0.25;
|
||
|
delY=0.25;
|
||
|
for j=1:NumY+1
|
||
|
for i=1:NumX+1
|
||
|
index=i+(NumX+1)*(j-1);
|
||
|
Node(index,1)=single((i-1.))*delX;
|
||
|
Node(index,2)=single((j-1.))*delY;
|
||
|
end
|
||
|
end
|
||
|
numNodes=(NumX+1)*(NumY+1);
|
||
|
for j=1:NumY
|
||
|
for i=1:NumX
|
||
|
index=i+NumX*(j-1);
|
||
|
Element(index,1)=i+(NumX+1)*(j-1);
|
||
|
Element(index,2)=i+(NumX+1)*(j-1)+1;
|
||
|
Element(index,3)=i+(NumX+1)*(j)+1;
|
||
|
Element(index,4)=i+(NumX+1)*(j);
|
||
|
end
|
||
|
end
|
||
|
numElem=(NumX)*(NumY);
|
||
|
% dofs per node
|
||
|
ndof=2;
|
||
|
% Define Section Properties
|
||
|
rho=1.;
|
||
|
% initial interface position
|
||
|
dpos=0.6;
|
||
|
% Initial temperatures
|
||
|
Tnew=zeros(numNodes*2,1);
|
||
|
Bound=zeros(numNodes*2,1);
|
||
|
stored(1)=dpos;
|
||
|
for e=1:numElem
|
||
|
for n=1:4
|
||
|
crdn=Node(Element(e,n),1);
|
||
|
if crdn<=dpos
|
||
|
Tnew(2*Element(e,n)-1)=1.;
|
||
|
end
|
||
|
if crdn<0.01
|
||
|
Bound(2*Element(e,n)-1)=1.;
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
% Define Time Step
|
||
|
dtime=0.01;
|
||
|
tsteps=10;
|
||
|
time=0.;
|
||
|
% penalty term
|
||
|
Penalty=50.;
|
||
|
% Loop through time steps
|
||
|
for ts=1:tsteps
|
||
|
eNodes=zeros(2*numNodes,1);
|
||
|
% Get interface velocity
|
||
|
d(1)=dpos+delX;
|
||
|
d(2)=dpos+3*delX/4;
|
||
|
d(3)=dpos+delX/4;
|
||
|
d(4)=dpos;
|
||
|
for e=1:numElem
|
||
|
crdn1=Node(Element(e,1),1);
|
||
|
crdn2=Node(Element(e,2),1);
|
||
|
for j=1:4
|
||
|
if d(j)>=crdn1 && d(j)<crdn2
|
||
|
elen=abs(crdn2-crdn1);
|
||
|
ajacob=elen/2.;
|
||
|
point=(d(j)-crdn1)/ajacob-1.;
|
||
|
theta(1)=abs(crdn1-dpos)*sign(crdn1-dpos);
|
||
|
theta(2)=abs(crdn2-dpos)*sign(crdn2-dpos);
|
||
|
tmp1a=Tnew(Element(e,1)*2-1);
|
||
|
tmp1b=Tnew(Element(e,1)*2);
|
||
|
tmp2a=Tnew(Element(e,2)*2-1);
|
||
|
tmp2b=Tnew(Element(e,2)*2);
|
||
|
xi=point;
|
||
|
gm(1)=(1.-xi)/2.;
|
||
|
gm(3)=(1.+xi)/2.;
|
||
|
term=theta(1)*gm(1)+theta(2)*gm(3);
|
||
|
gm(2)=gm(1)*(abs(term)-abs(theta(1)));
|
||
|
gm(4)=gm(3)*(abs(term)-abs(theta(2)));
|
||
|
t(j)=gm(1)*tmp1a+gm(2)*tmp1b+gm(3)*tmp2a+gm(4)*tmp2b;
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
% vel=-0.1*(0.5/delX)*(2*t(1)+t(2)-t(3)-2*t(4))
|
||
|
vel=0.0;
|
||
|
% Update interface position
|
||
|
dpos=dpos+vel*dtime;
|
||
|
stored(ts+1)=dpos;
|
||
|
K=zeros(numNodes*ndof,numNodes*ndof);
|
||
|
M=zeros(numNodes*ndof,numNodes*ndof);
|
||
|
pforce=zeros(numNodes*ndof,1);
|
||
|
% Loop Through Elements
|
||
|
for e=1:numElem
|
||
|
Ke=zeros(4*ndof);
|
||
|
Me=zeros(4*ndof);
|
||
|
for icrd=1:4;
|
||
|
crdnx(icrd)=Node(Element(e,icrd),1);
|
||
|
crdny(icrd)=Node(Element(e,icrd),2);
|
||
|
theta(icrd)=abs(crdnx(icrd)-dpos)*sign(crdnx(icrd)-dpos);
|
||
|
end
|
||
|
if sign(theta(1))~=sign(theta(2))
|
||
|
% possible enriched element
|
||
|
npart=10;
|
||
|
enr=npart*npart;
|
||
|
for sdx=1:npart
|
||
|
for sdy=1:npart
|
||
|
midx=-1.-1./npart+(2./npart)*sdx;
|
||
|
midy=-1.-1./npart+(2./npart)*sdy;
|
||
|
subindex=npart*(sdy-1)+sdx;
|
||
|
gpos=1./(sqrt(3.)*npart);
|
||
|
gx(subindex,1)=midx-gpos;
|
||
|
gx(subindex,2)=midx+gpos;
|
||
|
gx(subindex,3)=midx+gpos;
|
||
|
gx(subindex,4)=midx-gpos;
|
||
|
hx(subindex,1)=midy-gpos;
|
||
|
hx(subindex,2)=midy-gpos;
|
||
|
hx(subindex,3)=midy+gpos;
|
||
|
hx(subindex,4)=midy+gpos;
|
||
|
end
|
||
|
end
|
||
|
% check if int points are on different sides of front
|
||
|
check=0;
|
||
|
for i=1:enr
|
||
|
for j=1:4
|
||
|
g=gx(i,j);
|
||
|
h=hx(i,j);
|
||
|
phi(1)=0.25*(1.-g)*(1.-h);
|
||
|
phi(3)=0.25*(1.+g)*(1.-h);
|
||
|
phi(5)=0.25*(1.+g)*(1.+h);
|
||
|
phi(7)=0.25*(1.-g)*(1.+h);
|
||
|
iLS=theta(1)*phi(1)+theta(2)*phi(3)+theta(3)*phi(5)+theta(4)*phi(7);
|
||
|
if i==1 && j==1
|
||
|
sgn=sign(iLS);
|
||
|
else
|
||
|
if sign(iLS)~=sgn
|
||
|
check=1;
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
if check==0
|
||
|
% regular element - fix extra dofs
|
||
|
enr=1;
|
||
|
gpos=1/sqrt(3.);
|
||
|
gx(1,1)=-gpos;
|
||
|
gx(1,2)=gpos;
|
||
|
gx(1,3)=gpos;
|
||
|
gx(1,4)=-gpos;
|
||
|
hx(1,1)=-gpos;
|
||
|
hx(1,2)=-gpos;
|
||
|
hx(1,3)=gpos;
|
||
|
hx(1,4)=gpos;
|
||
|
end
|
||
|
else
|
||
|
% regular element - fix extra dofs
|
||
|
enr=1;
|
||
|
gpos=1/sqrt(3.);
|
||
|
gx(1,1)=-gpos;
|
||
|
gx(1,2)=gpos;
|
||
|
gx(1,3)=gpos;
|
||
|
gx(1,4)=-gpos;
|
||
|
hx(1,1)=-gpos;
|
||
|
hx(1,2)=-gpos;
|
||
|
hx(1,3)=gpos;
|
||
|
hx(1,4)=gpos;
|
||
|
end
|
||
|
% Loop Through Int Points
|
||
|
for i=1:enr
|
||
|
for j=1:4
|
||
|
g=gx(i,j);
|
||
|
h=hx(i,j);
|
||
|
phi(1)=0.25*(1.-g)*(1.-h);
|
||
|
phi(3)=0.25*(1.+g)*(1.-h);
|
||
|
phi(5)=0.25*(1.+g)*(1.+h);
|
||
|
phi(7)=0.25*(1.-g)*(1.+h);
|
||
|
iLS=theta(1)*phi(1)+theta(2)*phi(3)+theta(3)*phi(5)+theta(4)*phi(7);
|
||
|
cond=1.;
|
||
|
spec=1.;
|
||
|
for iter=1:4
|
||
|
phi(2*iter)=phi(2*iter-1)*(abs(iLS)-abs(theta(iter)));
|
||
|
end
|
||
|
phig(1)=0.25*-(1.-h);
|
||
|
phig(3)=0.25*(1.-h);
|
||
|
phig(5)=0.25*(1.+h);
|
||
|
phig(7)=0.25*-(1.+h);
|
||
|
phih(1)=0.25*-(1.-g);
|
||
|
phih(3)=0.25*-(1.+g);
|
||
|
phih(5)=0.25*(1.+g);
|
||
|
phih(7)=0.25*(1.-g);
|
||
|
diLSg=sign(iLS)*(phig(1)*theta(1)+phig(3)*theta(2)+phig(5)*theta(3)+phig(7)*theta(4));
|
||
|
diLSh=sign(iLS)*(phih(1)*theta(1)+phih(3)*theta(2)+phih(5)*theta(3)+phih(7)*theta(4));
|
||
|
for iter=1:4
|
||
|
phig(2*iter)=phig(2*iter-1)*(abs(iLS)-abs(theta(iter)))+phi(2*iter-1)*diLSg;
|
||
|
phih(2*iter)=phih(2*iter-1)*(abs(iLS)-abs(theta(iter)))+phi(2*iter-1)*diLSh;
|
||
|
end
|
||
|
rjac=zeros(2,2);
|
||
|
for iter=1:4
|
||
|
rjac(1,1)=rjac(1,1)+phig(2*iter-1)*crdnx(iter);
|
||
|
rjac(1,2)=rjac(1,2)+phig(2*iter-1)*crdny(iter);
|
||
|
rjac(2,1)=rjac(2,1)+phih(2*iter-1)*crdnx(iter);
|
||
|
rjac(2,2)=rjac(2,2)+phih(2*iter-1)*crdny(iter);
|
||
|
end
|
||
|
djac=rjac(1,1)*rjac(2,2)-rjac(1,2)*rjac(2,1);
|
||
|
rjaci(1,1)= rjac(2,2)/djac;
|
||
|
rjaci(2,2)= rjac(1,1)/djac;
|
||
|
rjaci(1,2)=-rjac(1,2)/djac;
|
||
|
rjaci(2,1)=-rjac(2,1)/djac ;
|
||
|
for iter=1:8
|
||
|
phix(iter)=rjaci(1,1)*phig(iter)+rjaci(1,2)*phih(iter);
|
||
|
phiy(iter)=rjaci(2,1)*phig(iter)+rjaci(2,2)*phih(iter);
|
||
|
end
|
||
|
we=djac;
|
||
|
Ke=Ke+(we*cond*(phix'*phix+phiy'*phiy))/double(enr);
|
||
|
Me=Me+((we*rho*spec*phi'*phi)/dtime)/double(enr);
|
||
|
end
|
||
|
end
|
||
|
% Add penalty term and get temp gradient on interface
|
||
|
if enr>1;
|
||
|
count=0;
|
||
|
if sign(theta(1))~=sign(theta(2))
|
||
|
count=count+1;
|
||
|
f=abs(theta(1))/(abs(theta(1))+abs(theta(2)));
|
||
|
xi(count)=f*(crdnx(2)-crdnx(1))+crdnx(1);
|
||
|
yi(count)=f*(crdny(2)-crdny(1))+crdny(1);
|
||
|
gi(count)=(2.*xi(count)-(crdnx(1)+crdnx(2)))/(-crdnx(1)+crdnx(2));
|
||
|
hi(count)=-1.;
|
||
|
end
|
||
|
if sign(theta(2))~=sign(theta(3))
|
||
|
count=count+1;
|
||
|
f=abs(theta(2))/(abs(theta(2))+abs(theta(3)));
|
||
|
xi(count)=f*(crdnx(3)-crdnx(2))+crdnx(2);
|
||
|
yi(count)=f*(crdny(3)-crdny(2))+crdny(2);
|
||
|
gi(count)=1.;
|
||
|
hi(count)=(2.*yi(count)-(crdny(2)+crdny(3)))/(-crdny(2)+crdny(3));
|
||
|
end
|
||
|
if sign(theta(3))~=sign(theta(4))
|
||
|
count=count+1;
|
||
|
f=abs(theta(3))/(abs(theta(3))+abs(theta(4)));
|
||
|
xi(count)=f*(crdnx(4)-crdnx(3))+crdnx(3);
|
||
|
yi(count)=f*(crdny(4)-crdny(3))+crdny(3);
|
||
|
gi(count)=(2.*xi(count)-(crdnx(4)+crdnx(3)))/(-crdnx(4)+crdnx(3));
|
||
|
hi(count)=1.;
|
||
|
end
|
||
|
if sign(theta(1))~=sign(theta(4))
|
||
|
count=count+1;
|
||
|
f=abs(theta(1))/(abs(theta(1))+abs(theta(4)));
|
||
|
xi(count)=f*(crdnx(4)-crdnx(1))+crdnx(1);
|
||
|
yi(count)=f*(crdny(4)-crdny(1))+crdny(1);
|
||
|
gi(count)=-1.;
|
||
|
hi(count)=(2.*yi(count)-(crdny(1)+crdny(4)))/(-crdny(4)+crdny(1));
|
||
|
end
|
||
|
c=zeros(2,1);
|
||
|
c=(c+1.);
|
||
|
for i=1:2;
|
||
|
G(i,1)=0.25*(1.-gi(i))*(1.-hi(i));
|
||
|
G(i,3)=0.25*(1.+gi(i))*(1.-hi(i));
|
||
|
G(i,5)=0.25*(1.+gi(i))*(1.+hi(i));
|
||
|
G(i,7)=0.25*(1.-gi(i))*(1.+hi(i));
|
||
|
G(i,2)=-G(i,1)*abs(theta(1));
|
||
|
G(i,4)=-G(i,3)*abs(theta(2));
|
||
|
G(i,6)=-G(i,5)*abs(theta(3));
|
||
|
G(i,8)=-G(i,7)*abs(theta(4));
|
||
|
end
|
||
|
pen=Penalty*(G'*G);
|
||
|
pfL=Penalty*G'*c;
|
||
|
Ke=Ke+pen;
|
||
|
else
|
||
|
pen=zeros(8);
|
||
|
pfL=zeros(8,1);
|
||
|
end
|
||
|
% Assemble Global Matrices
|
||
|
gnum(1)=2*Element(e,1)-1;
|
||
|
gnum(2)=2*Element(e,2)-1;
|
||
|
gnum(3)=2*Element(e,3)-1;
|
||
|
gnum(4)=2*Element(e,4)-1;
|
||
|
for i=1:4;
|
||
|
for j=1:4;
|
||
|
K(gnum(j),gnum(i))=K(gnum(j),gnum(i))+Ke(2*j-1,2*i-1);
|
||
|
K(gnum(j)+1,gnum(i))=K(gnum(j)+1,gnum(i))+Ke(2*j,2*i-1);
|
||
|
K(gnum(j),gnum(i)+1)=K(gnum(j),gnum(i)+1)+Ke(2*j-1,2*i);
|
||
|
K(gnum(j)+1,gnum(i)+1)=K(gnum(j)+1,gnum(i)+1)+Ke(2*j,2*i);
|
||
|
M(gnum(j),gnum(i))=M(gnum(j),gnum(i))+Me(2*j-1,2*i-1);
|
||
|
M(gnum(j)+1,gnum(i))=M(gnum(j)+1,gnum(i))+Me(2*j,2*i-1);
|
||
|
M(gnum(j),gnum(i)+1)=M(gnum(j),gnum(i)+1)+Me(2*j-1,2*i);
|
||
|
M(gnum(j)+1,gnum(i)+1)=M(gnum(j)+1,gnum(i)+1)+Me(2*j,2*i);
|
||
|
end
|
||
|
end
|
||
|
for i=1:4;
|
||
|
pforce(gnum(i))=pforce(gnum(i))+pfL(2*i-1);
|
||
|
pforce(gnum(i)+1)=pforce(gnum(i)+1)+pfL(2*i);
|
||
|
end
|
||
|
end
|
||
|
%Remove NON-ENHANCED DOFs(Reduce Matrices)
|
||
|
iindex=0.;
|
||
|
for i=1:ndof*numNodes;
|
||
|
check=0;
|
||
|
% if mod(i,2)==0 && eNodes(i)~=1
|
||
|
% check=1;
|
||
|
% end
|
||
|
if check==0
|
||
|
iindex=iindex+1;
|
||
|
TR1(iindex)=Tnew(i);
|
||
|
BR1(iindex)=Bound(i);
|
||
|
pforceR1(iindex)=pforce(i);
|
||
|
jindex=0;
|
||
|
for j=1:ndof*numNodes;
|
||
|
check=0;
|
||
|
% if mod(j,2)==0 && eNodes(j)~=1
|
||
|
% check=1;
|
||
|
% end
|
||
|
if check==0
|
||
|
jindex=jindex+1;
|
||
|
MR1(iindex,jindex)=M(i,j);
|
||
|
KR1(iindex,jindex)=K(i,j);
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
AR1=KR1+MR1;
|
||
|
SubR1=AR1*BR1';
|
||
|
RHSR1=MR1*TR1'-SubR1+pforceR1';
|
||
|
% Apply Boundary Conditions
|
||
|
Biindex=0.;
|
||
|
for i=1:iindex;
|
||
|
if BR1(i)==0.;
|
||
|
Biindex=Biindex+1;
|
||
|
RHSR2(Biindex)=RHSR1(i);
|
||
|
jindex=0;
|
||
|
for j=1:iindex;
|
||
|
check=0;
|
||
|
if BR1(j)==0.;
|
||
|
jindex=jindex+1;
|
||
|
AR2(Biindex,jindex)=AR1(i,j);
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
%Solve
|
||
|
Tnewr=(AR2^-1)*RHSR2';
|
||
|
% Restore Matrices
|
||
|
Biindex=0;
|
||
|
for i=1:iindex;
|
||
|
if BR1(i)==0.;
|
||
|
Biindex=Biindex+1;
|
||
|
TR1(i)=Tnewr(Biindex);
|
||
|
end
|
||
|
end
|
||
|
iindex=0;
|
||
|
for i=1:ndof*numNodes;
|
||
|
check=0;
|
||
|
% if mod(i,2)==0 && eNodes(i)~=1
|
||
|
% check=1;
|
||
|
% end
|
||
|
if check==0
|
||
|
iindex=iindex+1;
|
||
|
Tnew(i)=TR1(iindex);
|
||
|
end
|
||
|
end
|
||
|
Tnew
|
||
|
end
|
||
|
stored';
|