phd-scripts/Unpublished/XFEM/2D_Solver/FESolveX2Db.m

272 lines
9 KiB
Mathematica
Raw Normal View History

2024-05-13 19:50:21 +00:00
function [] = FESolveX2Db()
% 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);
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=1;
time=0.;
% penalty term
Penalty=00.;
% Loop through time steps
for ts=1:tsteps
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))
if 1==2
% enriched element
enr=8;
% get interface position on element
elen=abs(crdnx(2)-crdnx(1));
frac=abs(dpos-crdnx(1))/elen;
len1=2.*frac;
len2=2.*(1.-frac);
% devide element for sub integration
mid1=-1+len1/2.;
mid2=1-len2/2.;
gx(1)=mid1-(len1/2.)/sqrt(3.);
gx(2)=mid1+(len1/2.)/sqrt(3.);
gx(3)=mid1+(len1/2.)/sqrt(3.);
gx(4)=mid1-(len1/2.)/sqrt(3.);
gx(5)=mid2-(len2/2.)/sqrt(3.);
gx(6)=mid2+(len2/2.)/sqrt(3.);
gx(7)=mid2+(len2/2.)/sqrt(3.);
gx(8)=mid2-(len2/2.)/sqrt(3.);
gpos=1/sqrt(3.);
hx(1)=-gpos;
hx(2)=-gpos;
hx(3)=+gpos;
hx(4)=+gpos;
hx(5)=-gpos;
hx(6)=-gpos;
hx(7)=+gpos;
hx(8)=+gpos;
for iw=1:4
w(iw)=frac/2.;
w(iw+4)=(1.-frac)/2.;
end
else
% regular element - fix extra dofs
enr=4;
gpos=1/sqrt(3.);
gx(1)=-gpos;
gx(2)=gpos;
gx(3)=gpos;
gx(4)=-gpos;
hx(1)=-gpos;
hx(2)=-gpos;
hx(3)=gpos;
hx(4)=gpos;
for iw=1:4
w(iw)=1.;
end
end
% Loop Through Int Points
for i=1:enr;
g=gx(i);
h=hx(i);
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=w(i)*djac;
B=[phix;phiy];
% Ke=Ke+we*cond*(phix'*phix+phiy'*phiy);
Ke=Ke+we*cond*(B'*B);
Me=Me+(we*rho*spec*phi'*phi)/dtime;
end
% Add penalty term and get temp gradient on interface
if enr==8;
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 inactive DOFs(Reduce Matrices)
A=K+M;
Sub=A*Bound;
RHS=M*Tnew-Sub+pforce;
iindex=0;
for i=1:ndof*numNodes;
if Bound(i)==0.;
iindex=iindex+1;
RHSR(iindex)=RHS(i);
jindex=0;
for j=1:ndof*numNodes;
if Bound(j)==0.;
jindex=jindex+1;
AR(iindex,jindex)=A(i,j);
end
end
end
end
%Solve
Tnewr=(AR^-1)*RHSR';
iindex=0;
for i=1:ndof*numNodes;
if Bound(i)==0.;
iindex=iindex+1;
Tnew(i)=Tnewr(iindex);
end
end
Tnew
end