Add scripts and inp files.

This commit is contained in:
James Grogan 2024-05-13 20:50:21 +01:00
parent ad937f2602
commit e19f869a1e
390 changed files with 6580687 additions and 10 deletions

View file

@ -0,0 +1,202 @@
c 2D XFEM Corrosion Element
subroutine uel(rhs,amatrx,svars,energy,ndofel,nrhs,nsvars,props,
1 nprops,coords,mcrd,nnode,u,du,v,a,jtype,time,dtime,kstep,kinc,
2 jelem,params,ndload,jdltyp,adlmag,predef,npredf,lflags,
3 mlvarx,ddlmag,mdload,pnewdt,jprops,njprop,period)
c
include 'aba_param.inc'
c
dimension rhs(mlvarx,*),amatrx(ndofel,ndofel),svars(nsvars),
1 energy(8),props(*),coords(mcrd,nnode),
2 u(ndofel),du(mlvarx,*),v(ndofel),a(ndofel),time(2),
3 params(3),jdltyp(mdload,*),adlmag(mdload,*),
4 ddlmag(mdload,*),predef(2,npredf,nnode),lflags(*),jprops(*)
c
dimension phig(8),phih(8),phi(8),phix(8),phiy(8)
dimension crdnx(4),crdny(4),w(8),dndg(4),dndh(4)
dimension theta(4),rjac(2,2),rjaci(2,2)
c
parameter(zero=0.d0,one=1.d0)
c material property definition
thick = 1.
rho = 1.
beta=40.
vel=0.0
dpos=0.25+vel*time(2)
c initialization (nrhs=1)
do k1=1,ndofel
rhs(k1,nrhs)=zero
do k2=1,ndofel
amatrx(k2,k1)=zero
enddo
enddo
if (lflags(1).eq.33) then
do icrd=1,4
crdnx(icrd)=coords(1,icrd)
crdny(icrd)=coords(2,icrd)
theta(icrd)=abs(crdnx(icrd)-dpos)*
1 sign(1.,crdnx(icrd)-dpos)
enddo
if sign(1.,theta(1))/=sign(1.,theta(2))then
c Enriched
ienr=8
elen=abs(crdnx(2)-crdnx(1))
frac=abs(dpos-crdnx(1))/elen
rlen1=2.*frac
rlen2=2.*(1.-frac)
rmid1=-1+rlen1/2.
rmid2=1-rlen2/2.
gx(1)=rmid1-(rlen1/2.)/sqrt(3.)
gx(2)=rmid1+(rlen1/2.)/sqrt(3.)
gx(3)=rmid1+(rlen1/2.)/sqrt(3.)
gx(4)=rmid1-(rlen1/2.)/sqrt(3.)
gx(5)=rmid2-(rlen2/2.)/sqrt(3.)
gx(6)=rmid2+(rlen2/2.)/sqrt(3.)
gx(7)=rmid2+(rlen2/2.)/sqrt(3.)
gx(8)=rmid2-(rlen2/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
do iw=1,4
w(iw)=frac/2.;
w(iw+4)=(1.-frac)/2.;
enddo
else
c Normal Shp Funs
ienr=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
do iw=1,4
w(iw)=1.
enddo
endif
c assemble amatrx and rhs
do k=1,ienr
c loop through gauss pts
g=gx(k)
h=hx(k)
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)
riLS=theta(1)*phi(1)+theta(2)*phi(3)+
1 theta(3)*phi(5)+theta(4)*phi(7)
if (riLS<0.)then
cond=0.
spec=0.01
else
cond=1.
spec=1.
endif
do iter=1,4
phi(2*iter)=phi(2*iter-1)*
1 (abs(riLS)-abs(theta(iter)))
enddo
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(1.,iLS)*(phig(1)*theta(1)+phig(3)*
1 theta(2)+phig(5)*theta(3)+phig(7)*theta(4))
diLSh=sign(1.,iLS)*(phih(1)*theta(1)+phih(3)*
1 theta(2)+phih(5)*theta(3)+phih(7)*theta(4))
do iter=1,4
phig(2*iter)=phig(2*iter-1)*(abs(iLS)-
1 abs(theta(iter)))+phi(2*iter-1)*diLSg
phih(2*iter)=phih(2*iter-1)*(abs(iLS)-
1 abs(theta(iter)))+phi(2*iter-1)*diLSh
enddo
rjac=0.
do 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)
enddo
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
do 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)
enddo
dtdx=zero
dtdy=zero
t =zero
told=zero
do i=1,8
dtdx=u(i)*phix(i)+dtdx
dtdy=u(i)*phiy(i)+dtdy
t=u(i)*phi(i)+t
told=(u(i)-du(i,nrhs))*phi(i)+told
end do
dtdt=(t-told)/dtime
we=w(k)*djac
do ki=1,8
c loop over nodes
rhs(ki,nrhs) = rhs(ki,nrhs) -
1 we*(phi(ki)*rho*spec*dtdt +
2 cond*(phix(ki)*dtdx + phiy(ki)*dtdy))
do kj=1,8
amatrx(ki,kj)= amatrx(ki,kj) +
1 we*(phi(ki)*phi(kj)*rho*spec/dtime +
1 cond*(phix(ki)*phix(kj)+phiy(ki)*phiy(kj)))
end do
end do
enddo
c if interface is in the element a penalty term is needed
if(enr==4)then
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)))
term2=gm(1)*u(1)+gm(2)*u(2)+gm(3)*u(3)+gm(4)*u(4)
diff=abs(term2-1.)
c add penalty flux/force: BGtc
targetT=1.
do i=1,4
rhs(i,nrhs)=rhs(i,nrhs)+beta*gm(i)*diff
enddo
c find GtG
gm2=0.
do i=1,4
do j=1,4
gm2(i,j)=gm(i)*gm(j)
enddo
enddo
c add penalty stiffness
do i=1,4
do j=1,4
amatrx(i,j)=amatrx(i,j)+beta*gm2(i,j)
enddo
enddo
endif
end if
return
end

View file

@ -0,0 +1,78 @@
*Heading
** Job name: Job-1 Model name: Model-1
** Generated by: Abaqus/CAE 6.12-1
*Preprint, echo=NO, model=NO, history=NO, contact=NO
**
** PARTS
**
*Part, name=Part-1
*Node
1, 0., 0., 0.
2, 1., 0., 0.
3, 1., 1., 0.
4, 0., 1., 0.
5, 1., 2., 0.
6, 0., 2., 0.
*USER ELEMENT,NODES=4,TYPE=U1,PROP=1,COORDINATES=2,VAR=2,unsymm
11,
*Element, type=U1,ELSET=UEL
1, 1, 2,3,4
2, 4, 3,5,6
*UEL Property, Elset=UEL
1.
*End Part
**
**
** ASSEMBLY
**
*Assembly, name=Assembly
**
*Instance, name=Part-1-1, part=Part-1
*End Instance
**
*Nset, nset=_PickedSet16, internal, instance=Part-1-1
1,3,5
*Nset, nset=_PickedSet17, internal, instance=Part-1-1
2,4,6
*Nset, nset=Set-6, instance=Part-1-1
1,3,5
*End Assembly
**
** MATERIALS
**
*Material, name=Material-1
*Conductivity
1.,
*Density
1.,
*Specific Heat
1.,
** ----------------------------------------------------------------
**
** Name: Predefined Field-1 Type: Temperature
*Initial Conditions, type=TEMPERATURE
_PickedSet16, 1.,0.
** Name: Predefined Field-2 Type: Temperature
*Initial Conditions, type=TEMPERATURE
_PickedSet17, 0.,0.
** STEP: Step-1
**
*Step, name=Step-1
*Heat Transfer, end=PERIOD, deltmx=100.
0.1, 1., 1e-09, 0.1,
**
** BOUNDARY CONDITIONS
**
** Name: BC-1 Type: Temperature
*Boundary
Set-6, 11, 11, 1.
**
** OUTPUT REQUESTS
**
*Restart, write, frequency=0
**
** FIELD OUTPUT: F-Output-1
**
*Output, field, variable=PRESELECT
*Output, history, frequency=0
*End Step

View file

@ -0,0 +1,331 @@
function [] = F2DLevelSetFMM()
clear all
% Define Main Solution Mesh
NumX=32;
NumY=32;
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);
% Define Initial Level Set
centx=4.;
centy=4.;
rad=2.1;
for i=1:numNodes;
dist=sqrt((Node(i,1)-centx)*(Node(i,1)-centx)+(Node(i,2)-centy)*(Node(i,2)-centy));
lSet(i)=dist-rad;
end
%for i=1:numNodes;
% dist=Node(i,1)-0.1;
% lSet(i)=dist;
%end
% Plot initial level set
[X Y]=meshgrid(0:0.25:8);
Z=zeros(33);
for i=1:1089
Z(i)=lSet(i);
end
surf(X,Y,Z)
% LS Algorithm Parameters
lSet'
bandwidth=10;
% Loop through timesteps
for tstep=1:10
% Identify Narrow Band Elements
NBElems=0;
NBNodes=0;
NGlobal=zeros(numNodes);
for i=1:numElem
check=0;
for iNd=1:4
if abs(lSet(Element(i,iNd)))<=bandwidth*delX
check=1;
end
end
% If an element is in the narrow band split it into triangles
if check==1
for j=1:4
if NGlobal(Element(i,j))==0
NBNodes=NBNodes+1;
NGlobal(Element(i,j))=NBNodes;
NLocal(NBNodes)=Element(i,j);
end
end
NBElems=NBElems+1;
NBelem(NBElems,1)=NGlobal(Element(i,1));
NBelem(NBElems,2)=NGlobal(Element(i,2));
NBelem(NBElems,3)=NGlobal(Element(i,3));
NBElems=NBElems+1;
NBelem(NBElems,1)=NGlobal(Element(i,1));
NBelem(NBElems,2)=NGlobal(Element(i,3));
NBelem(NBElems,3)=NGlobal(Element(i,4));
end
end
% Get local Level Set
for i=1:NBNodes
lSetLocal(i)=lSet(NLocal(i));
end
% Velocity BC
F=zeros(NBNodes,1);
for i=1:NBElems
L1=sign(lSetLocal(NBelem(i,1)));
L2=sign(lSetLocal(NBelem(i,2)));
L3=sign(lSetLocal(NBelem(i,3)));
if L1 ~= L2 || L1 ~= L3
F(NBelem(i,1))= 1.;
F(NBelem(i,2))= 1.;
F(NBelem(i,3))= 1.;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(NBNodes);
for i=1:NBElems
gx(1)=2./3.;
gx(2)=1./6.;
gx(3)=1./6.;
hx(1)=1./6.;
hx(2)=1./6.;
hx(3)=2./3.;
AfL=zeros(3);
AfLGLS=zeros(3);
x1=Node(NLocal(NBelem(i,1)),1);
y1=Node(NLocal(NBelem(i,1)),2);
x2=Node(NLocal(NBelem(i,2)),1);
y2=Node(NLocal(NBelem(i,2)),2);
x3=Node(NLocal(NBelem(i,3)),1);
y3=Node(NLocal(NBelem(i,3)),2);
for j=1:3
g=gx(j);
h=hx(j);
phi(1)=1.-g-h;
phi(2)=g;
phi(3)=h;
phig(1)=-1.;
phig(2)=1.;
phig(3)=0.;
phih(1)=-1.;
phih(2)=0.;
phih(3)=1.;
djac=2*abs(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2));
for k=1:3
phix(k)=(1./djac)*((-y1+y3)*phig(k)+(y1-y2)*phih(k));
phiy(k)=(1./djac)*((x1-x3)*phig(k)+(-x1+x2)*phih(k));
end
delphi=[phix;phiy];
nodalLset=[lSetLocal(NBelem(i,1));lSetLocal(NBelem(i,2));lSetLocal(NBelem(i,3))];
set=phi*nodalLset;
delset=delphi*nodalLset;
AfL=AfL+(phi'*sign(set))*(delset'*delphi)/3.;
AfLGLS=AfLGLS+(delphi'*delset)*(1./norm(delset))*(delset'*delphi)/3.;
end
sum=AfL+AfLGLS;
for k=1:3;
for j=1:3;
A(NBelem(i,j),NBelem(i,k))=A(NBelem(i,j),NBelem(i,k))+sum(j,k);
end
end
end
% Apply BCs
RHS=zeros(NBNodes,1);
Sub=A*F;
iindex=0;
for i=1:NBNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:NBNodes
if F(j)==0.
jindex=jindex+1;
Ared(iindex,jindex)=A(i,j);
end
end
end
end
% Solve for Fred
Fred=(Ared^-1)*RHSred';
% Get F
iindex=0;
for i=1:NBNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(NBNodes);
mMatGLS=zeros(NBNodes);
f1=zeros(NBNodes,1);
f2=zeros(NBNodes,1);
f3=zeros(NBNodes,1);
h2=0.00001;
visc=0.0005;
for i=1:NBElems
mMatL=zeros(3);
mMatGLSL=zeros(3);
f1L=zeros(3,1);
f2L=zeros(3,1);
f3L=zeros(3,1);
gx(1)=2./3.;
gx(2)=1./6.;
gx(3)=1./6.;
hx(1)=1./6.;
hx(2)=1./6.;
hx(3)=2./3.;
x1=Node(NLocal(NBelem(i,1)),1);
y1=Node(NLocal(NBelem(i,1)),2);
x2=Node(NLocal(NBelem(i,2)),1);
y2=Node(NLocal(NBelem(i,2)),2);
x3=Node(NLocal(NBelem(i,3)),1);
y3=Node(NLocal(NBelem(i,3)),2);
for j=1:3
g=gx(j);
h=hx(j);
phi(1)=1.-g-h;
phi(2)=g;
phi(3)=h;
phig(1)=-1.;
phig(2)=1.;
phig(3)=0.;
phih(1)=-1.;
phih(2)=0.;
phih(3)=1.;
djac=abs(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2));
for k=1:3
phix(k)=(1./djac)*((-y1+y3)*phig(k)+(y1-y2)*phih(k));
phiy(k)=(1./djac)*((x1-x3)*phig(k)+(-x1+x2)*phih(k));
end
delphi=[phix;phiy];
nodalLset=[lSetLocal(NBelem(i,1));lSetLocal(NBelem(i,2));lSetLocal(NBelem(i,3))];
nodalF=[F(NBelem(i,1));F(NBelem(i,2));F(NBelem(i,3))];
delset=delphi*nodalLset;
Floc=phi*nodalF;
mMatL=mMatL+(phi'*phi)/3.;
mMatGLSL=mMatGLSL+((delphi'*(delset/norm(delset)))*Floc*(h2/abs(Floc)))*phi/3.;
f1L=f1L+phi'*Floc*norm(delset)/3.;
f2L=f2L+(delphi'*(delset/norm(delset))*Floc)*(h2/abs(Floc))*Floc*norm(delset)/3.;
vs=h2*((abs(visc+Floc*norm(delset)))/(norm(Floc*delset)+h2));
f3L=f3L+vs*delphi'*delset/3.;
end
for k=1:3;
for j=1:3;
mMat(NBelem(i,j),NBelem(i,k))=mMat(NBelem(i,j),NBelem(i,k))+mMatL(j,k);
mMatGLS(NBelem(i,j),NBelem(i,k))=mMatGLS(NBelem(i,j),NBelem(i,k))+mMatGLSL(j,k);
end
f1(NBelem(i,k))=f1(NBelem(i,k))+f1L(k);
f2(NBelem(i,k))=f2(NBelem(i,k))+f2L(k);
f3(NBelem(i,k))=f3(NBelem(i,k))+f3L(k);
end
end
dt=0.01;
lSetLocal=lSetLocal-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))';
newlSet=lSetLocal;
% Reinitialize LS
nstat=zeros(NBNodes,1);
for i=1:NBElems
L1=sign(lSetLocal(NBelem(i,1)));
L2=sign(lSetLocal(NBelem(i,2)));
L3=sign(lSetLocal(NBelem(i,3)));
if L1 ~= L2 || L1 ~= L3
for j=1:3
nstat(NBelem(i,j))=1;
end
end
end
maincheck=0;
while(maincheck==0)
lmin=1000.;
avlmin=1000.;
eindex=0;
nindex=0;
maincheck=1;
for i=1:NBElems
if nstat(NBelem(i,1))+nstat(NBelem(i,2))+nstat(NBelem(i,3))==2
maincheck=0;
check=0;
ltot=0.;
for j=1:3
if nstat(NBelem(i,j))==0
if abs(lSetLocal(NBelem(i,j)))<=lmin
check=1;
tempindex=j;
end
end
ltot=ltot+abs(lSetLocal(NBelem(i,j)));
end
if check==1 & ltot/3.<=avlmin
eindex=i;
nindex=tempindex;
lmin=lSetLocal(NBelem(eindex,nindex));
avlmin=ltot/3.;
end
end
end
if maincheck==0
% Find New LS for point
xp=Node(NLocal(NBelem(eindex,nindex)),1);
yp=Node(NLocal(NBelem(eindex,nindex)),2);
count=0;
for i=1:3
if i~=nindex
count=count+1;
x(count)=Node(NLocal(NBelem(eindex,i)),1);
y(count)=Node(NLocal(NBelem(eindex,i)),2);
lloc(count)=newlSet(NBelem(eindex,i));
end
end
delxa=x(1)-xp;
delya=y(1)-yp;
delxb=x(2)-xp;
delyb=y(2)-yp;
N=[delxa delya; delxb delyb];
M=N^-1;
A=(M(1)*M(1)+M(2)*M(2));
B=(M(3)*M(3)+M(4)*M(4));
C=2.*(M(1)*M(3)+M(2)*M(4));
a=A+B+C;
b=-2.*lloc(1)*A-2.*lloc(2)*B-C*(lloc(1)+lloc(2));
c=lloc(1)*lloc(1)*A+lloc(2)*lloc(2)*B+lloc(1)*lloc(2)*C-1.;
templ1=(-b+sqrt(b*b-4.*a*c))/(2.*a);
templ2=(-b-sqrt(b*b-4.*a*c))/(2.*a);
if abs(templ1)>abs(templ2)
newlSet(NBelem(eindex,nindex))=templ1;
else
newlSet(NBelem(eindex,nindex))=templ2;
end
nstat(NBelem(eindex,nindex))=1;
end
end
% lSetLocal=newlSet;
% Update Global Level Set
for i=1:NBNodes
lSet(NLocal(i))=lSetLocal(i);
end
end
lSet'
[X Y]=meshgrid(0:0.25:8);
Z=zeros(33);
for i=1:1089
Z(i)=lSet(i);
end
surf(X,Y,Z)

View file

@ -0,0 +1,165 @@
function [] = FESolve2DS()
% 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=1;
% 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.;
% 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);
end
% 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
% Loop Through Int Points
for i=1:enr;
g=gx(i);
h=hx(i);
phi(1)=0.25*(1.-g)*(1.-h);
phi(2)=0.25*(1.+g)*(1.-h);
phi(3)=0.25*(1.+g)*(1.+h);
phi(4)=0.25*(1.-g)*(1.+h);
cond=1.;
spec=1.;
phig(1)=0.25*-(1.-h);
phig(2)=0.25*(1.-h);
phig(3)=0.25*(1.+h);
phig(4)=0.25*-(1.+h);
phih(1)=0.25*-(1.-g);
phih(2)=0.25*-(1.+g);
phih(3)=0.25*(1.+g);
phih(4)=0.25*(1.-g);
rjac=zeros(2,2);
for iter=1:4
rjac(1,1)=rjac(1,1)+phig(iter)*crdnx(iter);
rjac(1,2)=rjac(1,2)+phig(iter)*crdny(iter);
rjac(2,1)=rjac(2,1)+phih(iter)*crdnx(iter);
rjac(2,2)=rjac(2,2)+phih(iter)*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:4
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;
Ke=Ke+we*cond*(phix'*phix+phiy'*phiy);
Me=Me+(we*rho*spec*phi'*phi)/dtime;
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(j,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)+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
stored';

View file

@ -0,0 +1,151 @@
function [] = FESolve2DS()
% 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);
% Define Section Properties
rho=1.;
% Initial temperatures
Tnew=zeros(numNodes,1);
Bound=zeros(numNodes,1);
for e=1:numElem
for n=1:4
crdn=Node(Element(e,n),1);
if crdn<=0.6
Tnew(Element(e,n))=1.;
end
if crdn<0.01
Bound(Element(e,n))=1.;
end
end
end
% Define Time Step
dtime=0.01;
tsteps=10;
time=0.;
% Loop through time steps
for ts=1:tsteps
K=zeros(numNodes,numNodes);
M=zeros(numNodes,numNodes);
% Loop Through Elements
for e=1:numElem
Ke=zeros(4);
Me=zeros(4);
for icrd=1:4;
crdnx(icrd)=Node(Element(e,icrd),1);
crdny(icrd)=Node(Element(e,icrd),2);
end
% regular element - fix extra dofs
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
% Loop Through Int Points
for i=1:4;
g=gx(i);
h=hx(i);
phi(1)=0.25*(1.-g)*(1.-h);
phi(2)=0.25*(1.+g)*(1.-h);
phi(3)=0.25*(1.+g)*(1.+h);
phi(4)=0.25*(1.-g)*(1.+h);
cond=1.;
spec=1.;
phig(1)=0.25*-(1.-h);
phig(2)=0.25*(1.-h);
phig(3)=0.25*(1.+h);
phig(4)=0.25*-(1.+h);
phih(1)=0.25*-(1.-g);
phih(2)=0.25*-(1.+g);
phih(3)=0.25*(1.+g);
phih(4)=0.25*(1.-g);
rjac=zeros(2,2);
for iter=1:4
rjac(1,1)=rjac(1,1)+phig(iter)*crdnx(iter);
rjac(1,2)=rjac(1,2)+phig(iter)*crdny(iter);
rjac(2,1)=rjac(2,1)+phih(iter)*crdnx(iter);
rjac(2,2)=rjac(2,2)+phih(iter)*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:4
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;
Ke=Ke+we*cond*(phix'*phix+phiy'*phiy);
Me=Me+(we*rho*spec*phi'*phi)/dtime;
end
% Assemble Global Matrices
gnum(1)=Element(e,1);
gnum(2)=Element(e,2);
gnum(3)=Element(e,3);
gnum(4)=Element(e,4);
for i=1:4;
for j=1:4;
K(gnum(j),gnum(i))=K(gnum(j),gnum(i))+Ke(j,i);
M(gnum(j),gnum(i))=M(gnum(j),gnum(i))+Me(j,i);
end
end
end
%Remove inactive DOFs(Reduce Matrices)
A=K+M;
Sub=A*Bound;
RHS=M*Tnew-Sub;
iindex=0;
for i=1:numNodes;
if Bound(i)==0.;
iindex=iindex+1;
RHSR(iindex)=RHS(i);
jindex=0;
for j=1: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:numNodes;
if Bound(i)==0.;
iindex=iindex+1;
Tnew(i)=Tnewr(iindex);
end
end
Tnew
end

View file

@ -0,0 +1,411 @@
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=00.;
% 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
eNodes(2*Element(e,1))=1;
eNodes(2*Element(e,2))=1;
eNodes(2*Element(e,3))=1;
eNodes(2*Element(e,4))=1;
% 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
if enr==8
phi(2*iter)=phi(2*iter-1)*(abs(iLS)-abs(theta(iter)));
else
phi(2*iter)=0.;
end
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
if enr==8
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;
else
phig(2*iter)=0.;
phih(2*iter)=0.;
end
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;
Ke=Ke+we*cond*(phix'*phix+phiy'*phiy);
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 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';

View file

@ -0,0 +1,364 @@
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';

View file

@ -0,0 +1,269 @@
function [] = FESolveX2DLS()
% MATLAB based 2-D XFEM Solver
% J. Grogan (2012)
clear all
% Define Mesh
NumX=3;
NumY=1;
delX=1.;
delY=1.;
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.1;
% 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.;
Bound(2*Element(e,n)-1)=1.;
end
end
end
% Define Time Step
dtime=0.1;
tsteps=20;
time=0.;
% penalty term
beta=80.;
% Loop through time steps
for ts=1:tsteps
% 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))
% 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);
if iLS<0.
cond=0.;
spec=0.01;
else
cond=1.;
spec=1.;
end
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;
Ke=Ke+we*cond*(phix'*phix+phiy'*phiy);
Me=Me+(we*rho*spec*phi'*phi)/dtime;
end
% Add penalty term and get temp gradient on interface
if enr==8;
xi=2.*frac-1;
yi=0.;
gm(1)=0.25*(1.-xi)*(1.-yi);
gm(3)=0.25*(1.+xi)*(1.-yi);
gm(5)=0.25*(1.+xi)*(1.+yi);
gm(7)=0.25*(1.-xi)*(1.+yi);
gm(2)=gm(1)*(-abs(theta(1)));
gm(4)=gm(3)*(-abs(theta(2)));
gm(6)=gm(5)*(-abs(theta(3)));
gm(8)=gm(7)*(-abs(theta(4)));
pen=beta*(gm'*gm);
pfL=beta*1.*gm';
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)+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)+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)
RHS=M*Tnew;
A=K+M;
Sub=A*Bound;
iindex=0;
for i=1:ndof*numNodes;
if Bound(i)==0.;
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i)+pforce(i);
jindex=0;
for j=1:ndof*numNodes;
if Bound(j)==0.;
jindex=jindex+1;
Ared(iindex,jindex)=A(i,j);
end
end
end
end
%Solve
StiffI=Ared^-1;
Tnewr=(Ared^-1)*RHSred';
iindex=0;
for i=1:ndof*numNodes;
if Bound(i)==0.;
iindex=iindex+1;
Tnew(i)=Tnewr(iindex);
end
end
Tnew
end
stored'

View file

@ -0,0 +1,305 @@
function [] = FESolveX2Db()
% MATLAB based 2-D XFEM Solver
% J. Grogan (2012)
clear all
% Define Mesh
NumX=2;
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.4;
% 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=1;
time=0.;
% penalty term
Penalty=00.;
% Loop through time steps
for ts=1:tsteps
% 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))
% 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;
Ke=Ke+we*cond*(phix'*phix+phiy'*phiy);
Me=Me+(we*rho*spec*phi'*phi)/dtime;
end
Me
% 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)+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)
M
A=K+M;
Sub=A*Bound;
M*Tnew;
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
stored';

View file

@ -0,0 +1,271 @@
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

View file

@ -0,0 +1,404 @@
! This Subroutine Implements the Level Set Method
! J. Grogan - 07/10/13
subroutine uexternaldb(lop,lrestart,time,dtime,kstep,kinc)
include 'aba_param.inc'
dimension time(2)
integer Element (100,4)
real Node(100,2),LSet(100)
!
if(lop==0)then
! Get Mesh Data
call getMesh(Element,Node,numElem,numNodes)
! Get Initial Level Set
call initialLSet(LSet,Node,numNodes)
elseif(lop==1)then
! Update Level Set
call updateLSet(Node,numNodes,Element,numElem,dtime,LSet)
endif
return
end
! This subroutine returns the finite element mesh connectivity data
subroutine getMesh(Element,Node,numElem,numNodes)
include 'aba_param.inc'
integer Element (100,4)
real Node(100,2)
character(256) outdir,jobname,input
call getoutdir(outdir,lenoutdir)
call getjobname(jobname,lenjobname)
filename=trim(outdir)//trim(jobname)//'.inp'
open(unit=107,file=filename,status='old')
read(107,*)input
do while (index(input,'*Node')==0)
read(107,*)input
enddo
ierr=0
numNodes=0
do while (ierr==0)
read(107,*)nodeNum,xcor,ycor,zcor
if(ierr==0)then
Node(nodeNum,1)=xcor
Node(nodeNum,2)=ycor
numNodes=numNodes+1
endif
enddo
do while (index(input,'*Element')==0)
read(107,*)input
enddo
numElem=0
do while (ierr==0)
read(107,*)elNum,n1,n2,n3,n4
if(ierr==0)then
Element(elNum,1)=n1
Element(elNum,2)=n2
Element(elNum,3)=n3
Element(elNum,4)=n4
numElem=numElem+1
endif
enddo
close(107)
end subroutine
! This subroutine calculates the initial Level Set
subroutine initialLSet(LSet,Node,numNodes)
include 'aba_param.inc'
real Node(100,2),LSet(100)
!centx=4.
!centy=4.
!rad=2.1
!do i=1,numNodes
! dist=sqrt((Node(i,1)-centx)*(Node(i,1)-centx)+(Node(i,2)-centy)*(Node(i,2)-centy))
! LSet(i)=dist-rad
!enddo
do i=1,numNodes
dist=Node(i,1)-0.1
LSet(i)=dist
enddo
end subroutine
! This subroutine updates the Level Set
subroutine updateLSet(Node,numNodes,Element,numElem,dtime,LSet)
include 'aba_param.inc'
integer Element(100,4),NBelem(100,4)
real Node(100,2),NGlobal(100,2),NLocal(100,2)
real LSet(100),LSetLocal(100),F(100),Fred(100)
real A(100,100),Ared(100,100),RHS(100),RHSred(100)
real M(100,100),MGL(100,100),f1(100),f2(100),f3(100)
! parameters
bandWidth=10.
av_Length=1.
h2=0.00001*av_Length
visc=0.0005
dt=0.01
! explicit update of Level Set
do istep=1:floor(dtime/dt)
! Identify Narrow Band Elements and Get Local Level Set
call getNarrowBand(NBelem,NBElems,NGlobal,NLocal,NBNodes,LSetLocal, &
& bandWidth,LSet,Element,numElem,numNodes)
! Identify Scalar Velocity on Nodes Crossed By Interface - F
call getF(F,LSetLocal,NBElems,NBNodes,NBelem)
! Get 'Stiffness' Matrix - A
call getA(A,Node,NLocal,NBelem,NBNodes,NBElems,LSetLocal)
! Apply BCs
RHS=-matmul(A,F)
iindex=0
do i=1,NBNodes
if (F(i)==0.)then
iindex=iindex+1
RHSred(iindex)=RHS(i)
jindex=0
do j=1,NBNodes
if (F(j)==0.)then
jindex=jindex+1;
Ared(iindex,jindex)=A(i,j)
endif
enddo
endif
enddo
! Solve for Fred
Fred=(Ared^-1)*RHSred'
! Get F
iindex=0
do i=1,NBNodes
if (F(i)==0.)then
iindex=iindex+1
F(i)=Fred(iindex)
endif
enddo
! Get Level Set Equation Terms
call getTerms(M,MGLS,f1,f2,f3,Node,NLocal,NBelem,NBNodes,NBElems,&
& LSetLocal,visc,h2,F)
LSetLocal=LSetLocal-((((M+MGLS)^-1)*dt)*(f1+f2+f3))'
! Reinitialize LS
!call fastMarch(LSetLocal,NBelem,Node,NLocal,NBNodes)
do i=1,NBNodes
LSet(NLocal(i))=LSetLocal(i)
end
enddo
end subroutine
! This subroutine identifies elements in the narrow band
subroutine getNarrowBand(NBelem,NBElems,NGlobal,NLocal,NBNodes,LSetLocal,&
& bandWidth,LSet,Element,numElem,numNodes)
include 'aba_param.inc'
integer Element(100,4),NBelem(100,4)
real Node(100,2),NGlobal(100,2),NLocal(100,2)
real LSet(100),LSetLocal(100)
! Identify Narrow Band Elements
NBElems=0
NBNodes=0
NGlobal=0.
do i=1,numElem
check=0
do iNd=1,4
if (abs(LSet(Element(i,iNd)))<=bandWidth*(delX+delY)/2.)then
check=1
endif
enddo
! If an element is in the narrow band split it into triangles
if (check==1)then
for j=1,4
if (NGlobal(Element(i,j))==0)then
NBNodes=NBNodes+1
NGlobal(Element(i,j))=NBNodes
NLocal(NBNodes)=Element(i,j)
endif
endddo
NBElems=NBElems+1
NBelem(NBElems,1)=NGlobal(Element(i,1))
NBelem(NBElems,2)=NGlobal(Element(i,2))
NBelem(NBElems,3)=NGlobal(Element(i,3))
NBElems=NBElems+1
NBelem(NBElems,1)=NGlobal(Element(i,1))
NBelem(NBElems,2)=NGlobal(Element(i,3))
NBelem(NBElems,3)=NGlobal(Element(i,4))
endif
enddo
! Get local Level Set
do i=1,NBNodes
LSetLocal(i)=LSet(NLocal(i))
enddo
end subroutine
! This subroutine extends the interface velocity throughout the computational domain
subroutine getF(F,LSetLocal,NBElems,NBNodes,NBelem)
include 'aba_param.inc'
real LSetLocal(100),F(100),L(3)
F=0.
do i=1,NBElems
do j=1,3
L(j)=sign(1.,LSetLocal(NBelem(i,j)))
enddo
if (L(1) /= L(2) .or. L(1) /= L(3))then
do j=1,3
F(NBelem(i,j))= 1.
enddo
endif
enddo
end subroutine
! This subroutine gets the 'stiffness' matrix - A
subroutine getA(A,Node,NLocal,NBelem,NBNodes,NBElems,LSetLocal)
include 'aba_param.inc'
integer NBelem(100,4)
real Node(100,2),NLocal(100,2)
real LSetLocal(100),A(100,100),AfL(3,3),AfLGLS(3,3)
real gx(3),hx(3),phi(3),phig(3),phih(3),phix(3),phiy(3)
A=0.
do i=1,NBElems
gx(1)=2./3.
gx(2)=1./6.
gx(3)=1./6.
hx(1)=1./6.
hx(2)=1./6.
hx(3)=2./3.
AfL=0.
AfLGLS=0.
x1=Node(NLocal(NBelem(i,1)),1)
y1=Node(NLocal(NBelem(i,1)),2)
x2=Node(NLocal(NBelem(i,2)),1)
y2=Node(NLocal(NBelem(i,2)),2)
x3=Node(NLocal(NBelem(i,3)),1)
y3=Node(NLocal(NBelem(i,3)),2)
do j=1,3
g=gx(j)
h=hx(j)
phi(1)=1.-g-h
phi(2)=g
phi(3)=h
phig(1)=-1.
phig(2)=1.
phig(3)=0.
phih(1)=-1.
phih(2)=0.
phih(3)=1.
djac=2.*abs(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2))
do k=1,3
phix(k)=(1./djac)*((-y1+y3)*phig(k)+(y1-y2)*phih(k))
phiy(k)=(1./djac)*((x1-x3)*phig(k)+(-x1+x2)*phih(k))
enddo
delphi=[phix;phiy]
nodalLset=[LSetLocal(NBelem(i,1));LSetLocal(NBelem(i,2));LSetLocal(NBelem(i,3))]
set=phi*nodalLset
delset=delphi*nodalLset
AfL=AfL+(phi'*sign(set))*(delset'*delphi)/3.
AfLGLS=AfLGLS+(delphi'*delset)*(1./norm(delset))*(delset'*delphi)/3.
enddo
do k=1,3
do j=1,3
A(NBelem(i,j),NBelem(i,k))=A(NBelem(i,j),NBelem(i,k))+AfL(j,k)+AfLGLS(j,k)
enddo
enddo
enddo
end subroutine
! This subroutine gets the neccessary terms for the level set equation
subroutine getTerms(M,MGLS,f1,f2,f3,Node,NLocal,NBelem,NBNodes,NBElems,&
& LSetLocal,visc,h2,F)
include 'aba_param.inc'
integer NBelem(100,4)
real Node(100,2),NLocal(100,2),LSetLocal(100)
real M(100,100),MGLS(100,100),f1(100),f2(100),f3(100)
real ML(3,3),MGLSL(3,3),f1L(3),f2L(3),f3L(3)
real gx(3),hx(3),phi(3),phig(3),phih(3),phix(3),phiy(3)
M=0.
MGLS=0.
f1=0.
f2=0.
f3=0.
do i=1,NBElems
ML=0.
MGLSL=0.
f1L=0.
f2L=0.
f3L=0.
gx(1)=2./3.
gx(2)=1./6.
gx(3)=1./6.
hx(1)=1./6.
hx(2)=1./6.
hx(3)=2./3.
x1=Node(NLocal(NBelem(i,1)),1)
y1=Node(NLocal(NBelem(i,1)),2)
x2=Node(NLocal(NBelem(i,2)),1)
y2=Node(NLocal(NBelem(i,2)),2)
x3=Node(NLocal(NBelem(i,3)),1)
y3=Node(NLocal(NBelem(i,3)),2)
do j=1,3
g=gx(j)
h=hx(j)
phi(1)=1.-g-h
phi(2)=g
phi(3)=h
phig(1)=-1.
phig(2)=1.
phig(3)=0.
phih(1)=-1.
phih(2)=0.
phih(3)=1.
djac=abs(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2))
do k=1,3
phix(k)=(1./djac)*((-y1+y3)*phig(k)+(y1-y2)*phih(k))
phiy(k)=(1./djac)*((x1-x3)*phig(k)+(-x1+x2)*phih(k))
end
delphi=[phix;phiy]
nodalLset=[LSetLocal(NBelem(i,1));LSetLocal(NBelem(i,2));LSetLocal(NBelem(i,3))]
nodalF=[F(NBelem(i,1));F(NBelem(i,2));F(NBelem(i,3))]
delset=delphi*nodalLset;
Floc=phi*nodalF
ML=ML+(phi'*phi)/3.
MGLSL=MGLSL+((delphi'*(delset/norm(delset)))*Floc*(h2/abs(Floc)))*phi/3.
f1L=f1L+phi'*Floc*norm(delset)/3.
f2L=f2L+(delphi'*(delset/norm(delset))*Floc)*(h2/abs(Floc))*Floc*norm(delset)/3.
vs=h2*((abs(visc+Floc*norm(delset)))/(norm(Floc*delset)+h2))
f3L=f3L+vs*delphi'*delset/3.
enddo
do k=1,3
do j=1,3
M(NBelem(i,j),NBelem(i,k))=M(NBelem(i,j),NBelem(i,k))+ML(j,k)
MGLS(NBelem(i,j),NBelem(i,k))=MGLS(NBelem(i,j),NBelem(i,k))+MGLSL(j,k)
enddo
f1(NBelem(i,k))=f1(NBelem(i,k))+f1L(k)
f2(NBelem(i,k))=f2(NBelem(i,k))+f2L(k)
f3(NBelem(i,k))=f3(NBelem(i,k))+f3L(k)
enddo
enddo
end subroutine
! This subroutine uses the fast marching method to re-initialize the level set
call fastMarch(LSetLocal,NBelem,Node,NLocal,NBNodes)
include 'aba_param.inc'
integer NBelem(100,4),nstat(100)
real Node(100,2),NLocal(100,2),LSetLocal(100),newlSet(100),L(3)
newlSet=LSetLocal
! Reinitialize LS
nstat=0
do i=1,NBElems
do j=1,3
L(j)=sign(1.,lSetLocal(NBelem(i,j)))
enddo
if (L(1) /= L(2) .or. L(1) /= L(3))then
do j=1,3
nstat(NBelem(i,j))=1
enddo
endif
enddo
maincheck=0
do while(maincheck==0)
lmin=1000.
avlmin=1000.
eindex=0
nindex=0
maincheck=1
do i=1,NBElems
if (nstat(NBelem(i,1))+nstat(NBelem(i,2))+nstat(NBelem(i,3))==2)then
maincheck=0
check=0
ltot=0.
do j=1,3
if (nstat(NBelem(i,j))==0)then
if (abs(lSetLocal(NBelem(i,j)))<=lmin)then
check=1
tempindex=j
endif
endif
ltot=ltot+abs(lSetLocal(NBelem(i,j)))
enddo
if (check==1 .and. ltot/3.<=avlmin)then
eindex=i
nindex=tempindex
lmin=lSetLocal(NBelem(eindex,nindex))
avlmin=ltot/3.
endif
endif
enddo
if (maincheck==0)then
! Find New LS for point
xp=Node(NLocal(NBelem(eindex,nindex)),1)
yp=Node(NLocal(NBelem(eindex,nindex)),2)
count=0
do i=1,3
if (i/=nindex)then
icount=icount+1
x(icount)=Node(NLocal(NBelem(eindex,i)),1)
y(icount)=Node(NLocal(NBelem(eindex,i)),2)
lloc(icount)=newlSet(NBelem(eindex,i))
endif
enddo
delxa=x(1)-xp
delya=y(1)-yp
delxb=x(2)-xp
delyb=y(2)-yp
N=[delxa delya; delxb delyb]
M=N^-1
A=(M(1)*M(1)+M(2)*M(2))
B=(M(3)*M(3)+M(4)*M(4))
C=2.*(M(1)*M(3)+M(2)*M(4))
a=A+B+C
b=-2.*lloc(1)*A-2.*lloc(2)*B-C*(lloc(1)+lloc(2))
c=lloc(1)*lloc(1)*A+lloc(2)*lloc(2)*B+lloc(1)*lloc(2)*C-1.
templ1=(-b+sqrt(b*b-4.*a*c))/(2.*a)
templ2=(-b-sqrt(b*b-4.*a*c))/(2.*a)
if (abs(templ1)>abs(templ2))then
newlSet(NBelem(eindex,nindex))=templ1
else
newlSet(NBelem(eindex,nindex))=templ2
endif
nstat(NBelem(eindex,nindex))=1
endif
enddo
LSetLocal=newlSet
end subroutine

View file

@ -0,0 +1,268 @@
function [] = XCOR1D()
% MATLAB based 1-D XFEM Solver
% J. Grogan (2012)
clear all
% Define Geometry
len=1.;
% Define Section Properties
rho=1.;
% Generate Mesh
numElem=4;
charlen=len/numElem;
ndCoords=linspace(0,len,numElem+1);
numNodes=size(ndCoords,2);
indx=1:numElem;
elemNodes(:,1)=indx;
elemNodes(:,2)=indx+1;
% dofs per node
ndof=2;
% initial interface position
dpos=0.6;
% Initial temperatures
Tnew=zeros(numNodes*2,1);
Bound=zeros(numNodes*2,1);
%storage
stored(1)=dpos;
for e=1:numElem
for n=1:2
crdn1=ndCoords(elemNodes(e,n));
if crdn1<=dpos
Tnew(2*elemNodes(e,n)-1)=1.;
end
end
end
Bound(1)=1.;
% Define Time Step
dtime=0.01;
tsteps=10;
time=0.;
% penalty term
beta=100.;
% Loop through time steps
for ts=1:tsteps
eNodes=zeros(2*numNodes,1);
% Get interface velocity
d(1)=dpos+charlen;
d(2)=dpos+3*charlen/4;
d(3)=dpos+charlen/4;
d(4)=dpos;
for e=1:numElem
crdn1=ndCoords(elemNodes(e,1));
crdn2=ndCoords(elemNodes(e,2));
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(elemNodes(e,1)*2-1);
tmp1b=Tnew(elemNodes(e,1)*2);
tmp2a=Tnew(elemNodes(e,2)*2-1);
tmp2b=Tnew(elemNodes(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.5*(0.5/charlen)*(2*t(1)+t(2)-t(3)-2*t(4));
vel=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(2*ndof);
Me=zeros(2*ndof);
crdn1=ndCoords(elemNodes(e,1));
crdn2=ndCoords(elemNodes(e,2));
theta(1)=abs(crdn1-dpos)*sign(crdn1-dpos);
theta(2)=abs(crdn2-dpos)*sign(crdn2-dpos);
enr=2;
elen=abs(crdn2-crdn1);
ajacob=elen/2.;
if sign(theta(1))~=sign(theta(2))
% enriched element
eNodes(2*elemNodes(e,1))=1;
eNodes(2*elemNodes(e,2))=1;
enr=4;
% get interface position on element
point=(dpos-crdn1)/ajacob-1.;
% devide element for sub integration
len1=abs(-point-1.);
len2=abs(1.-point);
mid1=-1+len1/2.;
mid2=1-len2/2.;
gpx(1)=-(len1/2.)/sqrt(3.)+mid1;
gpx(2)=(len1/2.)/sqrt(3.)+mid1;
gpx(3)=-(len2/2.)/sqrt(3.)+mid2;
gpx(4)=(len2/2.)/sqrt(3.)+mid2;
w(1)=(len1/2.);
w(2)=(len1/2.);
w(3)=(len2/2.);
w(4)=(len2/2.);
else
% regular element - fix extra dofs
gpx(1)=-1/sqrt(3.);
gpx(2)=1/sqrt(3.);
w(1)=1.;
w(2)=1.;
end
% Loop Through Int Points
for i=1:enr;
c=gpx(i);
phi(1)=(1.-c)/2.;
phi(3)=(1.+c)/2.;
term=theta(1)*phi(1)+theta(2)*phi(3);
% if term<0
% cond=0.00;
% spec=0.001;
% else
cond=1.;
spec=1.;
% end
if enr==4
phi(2)=phi(1)*(abs(term)-abs(theta(1)));
phi(4)=phi(3)*(abs(term)-abs(theta(2)));
else
phi(2)=0.0;
phi(4)=0.0;
end
phic(1)=-0.5;
phic(3)=0.5;
dterm=sign(term)*(phic(1)*theta(1)+phic(3)*theta(2));
if enr==4
phic(2)=phic(1)*(abs(term)-abs(theta(1)))+phi(1)*dterm;
phic(4)=phic(3)*(abs(term)-abs(theta(2)))+phi(3)*dterm;
else
phic(2)=0.0;
phic(4)=0.0;
end
phix(1)=phic(1)/ajacob;
phix(2)=phic(2)/ajacob;
phix(3)=phic(3)/ajacob;
phix(4)=phic(4)/ajacob;
we=ajacob*w(i);
Ke=Ke+we*cond*phix'*phix;
Me=Me+(we*rho*spec*phi'*phi)/dtime;
end
if enr==5;
Ke(1,2)=0.;
Me(1,2)=0.;
Ke(2,1)=0.;
Me(2,1)=0.;
Ke(1,4)=0.;
Me(1,4)=0.;
Ke(4,1)=0.;
Me(4,1)=0.;
Ke(3,2)=0.;
Me(3,2)=0.;
Ke(2,3)=0.;
Me(2,3)=0.;
Ke(4,3)=0.;
Me(4,3)=0.;
Ke(3,4)=0.;
Me(3,4)=0.;
end
% Add penalty term and get temp gradient on interface
if enr==4;
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)));
pen=beta*(gm'*gm);
pfL=beta*1*gm';
Ke=Ke+pen;
else
pen=zeros(4);
pfL=zeros(4,1);
end
% Assemble Global Matrices
gnum=2.*elemNodes(e,1)-1.;
for i=1:4;
for j=1:4;
K(gnum+j-1,gnum+i-1)=K(gnum+j-1,gnum+i-1)+Ke(j,i);
M(gnum+j-1,gnum+i-1)=M(gnum+j-1,gnum+i-1)+Me(j,i);
end
pforce(gnum+i-1)=pforce(gnum+i-1)+pfL(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';

View file

@ -0,0 +1,196 @@
function [] = XCOR1Db()
% MATLAB based 1-D XFEM Solver
% J. Grogan (2012)
clear all
% Define Geometry
len=1.;
% Define Section Properties
rho=1.;
% Generate Mesh
numElem=4;
charlen=len/numElem;
ndCoords=linspace(0,len,numElem+1);
numNodes=size(ndCoords,2);
indx=1:numElem;
elemNodes(:,1)=indx;
elemNodes(:,2)=indx+1;
% dofs per node
ndof=2;
% initial interface position
dpos=0.6;
% Initial temperatures
Tnew=zeros(numNodes*2,1);
Bound=zeros(numNodes*2,1);
%storage
stored(1)=dpos;
for e=1:numElem
for n=1:2
crdn1=ndCoords(elemNodes(e,n));
if crdn1<=dpos
Tnew(2*elemNodes(e,n)-1)=1.;
end
end
end
Bound(1)=1.;
% Define Time Step
dtime=0.01;
tsteps=10;
time=0.;
% penalty term
beta=100.;
% Loop through time steps
for ts=1:tsteps
% Get interface velocity
d(1)=dpos+charlen;
d(2)=dpos+3*charlen/4;
d(3)=dpos+charlen/4;
d(4)=dpos;
for e=1:numElem
crdn1=ndCoords(elemNodes(e,1));
crdn2=ndCoords(elemNodes(e,2));
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(elemNodes(e,1)*2-1);
tmp1b=Tnew(elemNodes(e,1)*2);
tmp2a=Tnew(elemNodes(e,2)*2-1);
tmp2b=Tnew(elemNodes(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.5*(0.5/charlen)*(2*t(1)+t(2)-t(3)-2*t(4));
vel=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(2*ndof);
Me=zeros(2*ndof);
crdn1=ndCoords(elemNodes(e,1));
crdn2=ndCoords(elemNodes(e,2));
theta(1)=abs(crdn1-dpos)*sign(crdn1-dpos);
theta(2)=abs(crdn2-dpos)*sign(crdn2-dpos);
enr=2;
elen=abs(crdn2-crdn1);
ajacob=elen/2.;
if sign(theta(1))~=sign(theta(2))
% enriched element
enr=4;
% get interface position on element
point=(dpos-crdn1)/ajacob-1.;
% devide element for sub integration
len1=abs(-point-1.);
len2=abs(1.-point);
mid1=-1+len1/2.;
mid2=1-len2/2.;
gpx(1)=-(len1/2.)/sqrt(3.)+mid1;
gpx(2)=(len1/2.)/sqrt(3.)+mid1;
gpx(3)=-(len2/2.)/sqrt(3.)+mid2;
gpx(4)=(len2/2.)/sqrt(3.)+mid2;
w(1)=(len1/2.);
w(2)=(len1/2.);
w(3)=(len2/2.);
w(4)=(len2/2.);
else
% regular element - fix extra dofs
gpx(1)=-1/sqrt(3.);
gpx(2)=1/sqrt(3.);
w(1)=1.;
w(2)=1.;
end
% Loop Through Int Points
for i=1:enr;
c=gpx(i);
phi(1)=(1.-c)/2.;
phi(3)=(1.+c)/2.;
term=theta(1)*phi(1)+theta(2)*phi(3);
cond=1.;
spec=1.;
phi(2)=phi(1)*(abs(term)-abs(theta(1)));
phi(4)=phi(3)*(abs(term)-abs(theta(2)));
phic(1)=-0.5;
phic(3)=0.5;
dterm=sign(term)*(phic(1)*theta(1)+phic(3)*theta(2));
phic(2)=phic(1)*(abs(term)-abs(theta(1)))+phi(1)*dterm;
phic(4)=phic(3)*(abs(term)-abs(theta(2)))+phi(3)*dterm;
phix(1)=phic(1)/ajacob;
phix(2)=phic(2)/ajacob;
phix(3)=phic(3)/ajacob;
phix(4)=phic(4)/ajacob;
we=ajacob*w(i);
Ke=Ke+we*cond*phix'*phix
Me=Me+(we*rho*spec*phi'*phi)/dtime;
end
Me
% Add penalty term and get temp gradient on interface
if enr==4;
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)));
pen=beta*(gm'*gm);
pfL=beta*1*gm';
Ke=Ke+pen;
else
pen=zeros(4);
pfL=zeros(4,1);
end
% Assemble Global Matrices
gnum=2.*elemNodes(e,1)-1.;
for i=1:4;
for j=1:4;
K(gnum+j-1,gnum+i-1)=K(gnum+j-1,gnum+i-1)+Ke(j,i);
M(gnum+j-1,gnum+i-1)=M(gnum+j-1,gnum+i-1)+Me(j,i);
end
pforce(gnum+i-1)=pforce(gnum+i-1)+pfL(i);
end
end
A=K+M;
Sub=A*Bound;
M*Tnew;
RHS=M*Tnew-Sub+pforce;
% Apply Boundary Conditions
Biindex=0.;
for i=1:ndof*numNodes;
if Bound(i)==0.;
Biindex=Biindex+1;
RHSR(Biindex)=RHS(i);
jindex=0;
for j=1:ndof*numNodes;
if Bound(j)==0.;
jindex=jindex+1;
AR(Biindex,jindex)=A(i,j);
end
end
end
end
%Solve
Tnewr=(AR^-1)*RHSR';
% Restore Matrices
Biindex=0;
for i=1:ndof*numNodes;
if Bound(i)==0.;
Biindex=Biindex+1;
Tnew(i)=Tnewr(Biindex);
end
end
Tnew
end
stored';

View file

@ -0,0 +1,783 @@
function []=XCOR_2D()
clear all
% Define Mesh
NumX=2;
NumY=1;
delX=1.;
delY=1.;
numElem=NumX*NumY;
numNodes=(NumX+1)*(NumY+1);
Elength=(delX+delY)/2.;
[Node,Element]=buildMesh(NumX,NumY,delX,delY);
% Simulation Parameters
rho=1.;
Penalty=80.;
dtImp=0.1;
dtExp=0.01;
tsteps=4;
bandWidth=10.;
epsilon=0.00001;
visc=0.0005;
% Get Initial Level Set
LSetOld=initialLSet(Node,numNodes);
% plotLSet(NumX,NumY,delX,delY,LSet);
% Initial Conditions
Temp=zeros(numNodes*2,1);
for i=1:numNodes
if LSetOld(i)<=0
Temp(2*i-1)=1.;
end
end
% Boundary Conditions
Bound=zeros(numNodes*2,1);
for i=1:numNodes
if Node(i,1)<delX/10.
Bound(2*i-1)=1.;
end
end
% Loop through time steps
for ts=1:tsteps
% Update Level Set
LSetNew=updateLSet(Temp,Node,numNodes,Element,numElem,dtImp,dtExp,LSetOld,...
Elength,bandWidth,epsilon,visc);
% Solve for Temperature
Temp=getTemp(Node,Element,numNodes,numElem,LSetNew,Bound,Temp,Penalty,rho,dtImp,LSetOld);
LSetOld=LSetNew;
LSetOld'
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create a linear quadrilateral FE mesh
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [Node,Element]=buildMesh(NumX,NumY,delX,delY)
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
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
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This function updates the level set
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [LSet]=updateLSet(Temp,Node,numNodes,Element,numElem,dtImp,dtExp,LSet,...
Elength,bandWidth,epsilon,visc)
% parameters
charLen=epsilon*Elength;
for tstep=1:floor(dtImp/dtExp)
% Identify Narrow Band Elements and Get Local Level Set
[NBelem,NBElems,NGlobal,NLocal,NBNodes,LSetLocal]=getNarrowBand(bandWidth,...
Elength,LSet,Element,numElem,numNodes);
% Identify Scalar Velocity on Nodes Crossed By Interface - F
F=getF(Temp,LSetLocal,NBElems,NBNodes,NLocal,NBelem,Node,Elength);
% Get 'Stiffness' Matrix - A
A=getA(Node,NLocal,NBelem,NBNodes,NBElems,LSetLocal);
% Apply BCs
RHS=-A*F;
iindex=0;
for i=1:NBNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i);
jindex=0;
for j=1:NBNodes
if F(j)==0.
jindex=jindex+1;
Ared(iindex,jindex)=A(i,j);
end
end
end
end
if iindex>0
% Solve for Fred
Fred=(Ared^-1)*RHSred';
% Get F
iindex=0;
for i=1:NBNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
end
% Get Level Set Equation Terms
[M,MGLS,f1,f2,f3]=getTerms(Node,NLocal,NBelem,NBNodes,NBElems,LSetLocal,visc,charLen,F);
LSetLocal=LSetLocal-((((M+MGLS)^-1)*dtExp)*(f1+f2+f3))';
% Reinitialize LS
%LSetLocal=fastMarch(LSetLocal,NBelem,Node,NLocal,NBNodes,NBElems);
for i=1:NBNodes
LSet(NLocal(i))=LSetLocal(i);
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Find elements in narrow band and create map between
% global node labels and those in narrow band
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [NBelem,NBElems,NGlobal,NLocal,NBNodes,LSetLocal]=getNarrowBand(bandWidth,...
ELength,LSet,Element,numElem,numNodes)
% Identify Narrow Band Elements
NBElems=0;
NBNodes=0;
NGlobal=zeros(numNodes);
for i=1:numElem
check=0;
for iNd=1:4
if abs(LSet(Element(i,iNd)))<=bandWidth*ELength
check=1;
end
end
% If an element is in the narrow band split it into triangles
if check==1
for j=1:4
if NGlobal(Element(i,j))==0
NBNodes=NBNodes+1;
NGlobal(Element(i,j))=NBNodes;
NLocal(NBNodes)=Element(i,j);
end
end
NBElems=NBElems+1;
NBelem(NBElems,1)=NGlobal(Element(i,1));
NBelem(NBElems,2)=NGlobal(Element(i,2));
NBelem(NBElems,3)=NGlobal(Element(i,3));
NBElems=NBElems+1;
NBelem(NBElems,1)=NGlobal(Element(i,1));
NBelem(NBElems,2)=NGlobal(Element(i,3));
NBelem(NBElems,3)=NGlobal(Element(i,4));
end
end
% Get local Level Set
for i=1:NBNodes
LSetLocal(i)=LSet(NLocal(i));
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Get Interface Normal Veloctiy 'F'
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function F=getF(Temp,LSetLocal,NBElems,NBNodes,NLocal,NBelem,Node,ELength)
F=zeros(NBNodes,1);
eStat=zeros(NBElems,1);
nData=zeros(NBNodes,2);
for i=1:NBElems
for j=1:3
L(j)=LSetLocal(NBelem(i,j));
end
x11=Node(NLocal(NBelem(i,1)),1);
x12=Node(NLocal(NBelem(i,2)),1);
x13=Node(NLocal(NBelem(i,3)),1);
y11=Node(NLocal(NBelem(i,1)),2);
y12=Node(NLocal(NBelem(i,2)),2);
y13=Node(NLocal(NBelem(i,3)),2);
count=0.;
if sign(L(1)) ~= sign(L(2))
eStat(i)=1;
count=count+1;
f=abs(L(1))/(abs(L(1))+abs(L(2)));
xi(count)=f*(x12-x11)+x11;
yi(count)=f*(y12-y11)+y11;
end
if sign(L(1)) ~= sign(L(3))
eStat(i)=1;
count=count+1;
f=abs(L(1))/(abs(L(1))+abs(L(3)));
xi(count)=f*(x13-x11)+x11;
yi(count)=f*(y13-y11)+y11 ;
end
if sign(L(2)) ~= sign(L(3))
eStat(i)=1;
count=count+1;
f=abs(L(2))/(abs(L(2))+abs(L(3)));
xi(count)=f*(x13-x12)+x12;
yi(count)=f*(y13-y12)+y12 ;
end
if eStat(i)==1
n=[yi(2)-yi(1); xi(1)-xi(2)];
n=n/norm(n);
xd(1,1)=(xi(1)+xi(2))/2.;
xd(1,2)=(yi(1)+yi(2))/2.;
xd(2,1)=0.1*ELength*n(1)+xd(1,1);
xd(2,2)=0.1*ELength*n(2)+xd(1,2);
% Check if xd2 is in element
v0(1)=x11;
v0(2)=y11;
v1(1)=x12-x11;
v1(2)=y12-y11;
v2(1)=x13-x11;
v2(2)=y13-y11;
v(1)=xd(2,1);
v(2)=xd(2,2);
ra=((v(1)*v2(2)-v2(1)*v(2))-(v0(1)*v2(2)-v2(1)*v0(2)))/(v1(1)*v2(2)-v2(1)*v1(2));
rb=-((v(1)*v1(2)-v1(1)*v(2))-(v0(1)*v1(2)-v1(1)*v0(2)))/(v1(1)*v2(2)-v2(1)*v1(2));
check=0;
if ra>0. && rb>0. && ra+rb<1.
index=i;
x21=x11;
x22=x12;
x23=x13;
y21=y11;
y22=y12;
y23=y13;
else
for j=1:NBElems
tx1=Node(NLocal(NBelem(j,1)),1);
tx2=Node(NLocal(NBelem(j,2)),1);
tx3=Node(NLocal(NBelem(j,3)),1);
ty1=Node(NLocal(NBelem(j,1)),2);
ty2=Node(NLocal(NBelem(j,2)),2);
ty3=Node(NLocal(NBelem(j,3)),2);
v0(1)=tx1;
v0(2)=ty1;
v1(1)=tx2-tx1;
v1(2)=ty2-ty1;
v2(1)=tx3-tx1;
v2(2)=ty3-ty1;
v(1)=xd(2,1);
v(2)=xd(2,2);
ra=((v(1)*v2(2)-v2(1)*v(2))-(v0(1)*v2(2)-v2(1)*v0(2)))/(v1(1)*v2(2)-v2(1)*v1(2));
rb=-((v(1)*v1(2)-v1(1)*v(2))-(v0(1)*v1(2)-v1(1)*v0(2)))/(v1(1)*v2(2)-v2(1)*v1(2));
if ra>0. && rb>0. && ra+rb<1.
index=j;
x21=tx1;
x22=tx2;
x23=tx3;
y21=ty1;
y22=ty2;
y23=ty3;
end
end
end
Ae1=0.5*((x12*y13-x13*y12)+(y12-y13)*x11+(x13-x12)*y11);
Ae2=0.5*((x22*y23-x23*y22)+(y22-y23)*x21+(x23-x22)*y21);
N1=(1./(2.*Ae))*((y2-y3)*(xd(j,1)-x2)+(x3-x2)*(xd(j,2)-y2));
N2=(1./(2.*Ae))*((y3-y1)*(xd(j,1)-x3)+(x1-x3)*(xd(j,2)-y3));
N3=(1./(2.*Ae))*((y1-y2)*(xd(j,1)-x1)+(x2-x1)*(xd(j,2)-y1));
T1=Temp(2*NLocal(NBelem(i,1))-1);
T2=Temp(2*NLocal(NBelem(i,2))-1);
T3=Temp(2*NLocal(NBelem(i,3))-1);
a1=Temp(2*NLocal(NBelem(i,1)));
a2=Temp(2*NLocal(NBelem(i,2)));
a3=Temp(2*NLocal(NBelem(i,3)));
L1=LSetLocal(NBelem(i,1));
L2=LSetLocal(NBelem(i,2));
L3=LSetLocal(NBelem(i,3));
LS=abs(N1*L1+L2*N2+L3*N3);
p1=N1*(LS-abs(L1));
p2=N2*(LS-abs(L2));
p3=N3*(LS-abs(L3));
T(j)=N1*T1+N2*T2+N3*T3+p1*a1+p2*a2+p3*a3;
end
gradT=(T(2)-T(1))/(0.1*ELength);
for j=1:3
nData(NBelem(i,j),1)=nData(NBelem(i,j),1)+1.;
nData(NBelem(i,j),2)=nData(NBelem(i,j),2)+0.1*gradT;
end
end
end
for i=1:NBNodes
if nData(i,1)>0
F(i)=nData(i,2)/nData(i,1);
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Get 'Stiffness' Matrix 'A'
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [A]=getA(Node,NLocal,NBelem,NBNodes,NBElems,LSetLocal)
A=zeros(NBNodes);
for i=1:NBElems
gx(1)=2./3.;
gx(2)=1./6.;
gx(3)=1./6.;
hx(1)=1./6.;
hx(2)=1./6.;
hx(3)=2./3.;
AfL=zeros(3);
AfLGLS=zeros(3);
x1=Node(NLocal(NBelem(i,1)),1);
y1=Node(NLocal(NBelem(i,1)),2);
x2=Node(NLocal(NBelem(i,2)),1);
y2=Node(NLocal(NBelem(i,2)),2);
x3=Node(NLocal(NBelem(i,3)),1);
y3=Node(NLocal(NBelem(i,3)),2);
for j=1:3
g=gx(j);
h=hx(j);
phi(1)=1.-g-h;
phi(2)=g;
phi(3)=h;
phig(1)=-1.;
phig(2)=1.;
phig(3)=0.;
phih(1)=-1.;
phih(2)=0.;
phih(3)=1.;
djac=2*abs(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2));
for k=1:3
phix(k)=(1./djac)*((-y1+y3)*phig(k)+(y1-y2)*phih(k));
phiy(k)=(1./djac)*((x1-x3)*phig(k)+(-x1+x2)*phih(k));
end
delphi=[phix;phiy];
nodalLset=[LSetLocal(NBelem(i,1));LSetLocal(NBelem(i,2));LSetLocal(NBelem(i,3))];
set=phi*nodalLset;
delset=delphi*nodalLset;
AfL=AfL+(phi'*sign(set))*(delset'*delphi)/3.;
AfLGLS=AfLGLS+(delphi'*delset)*(1./norm(delset))*(delset'*delphi)/3.;
end
sum=AfL+AfLGLS;
for k=1:3;
for j=1:3;
A(NBelem(i,j),NBelem(i,k))=A(NBelem(i,j),NBelem(i,k))+sum(j,k);
end
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Get terms for LS equation
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [M,MGLS,f1,f2,f3]=getTerms(Node,NLocal,NBelem,NBNodes,NBElems,LSetLocal,visc,charLen,F)
M=zeros(NBNodes);
MGLS=zeros(NBNodes);
f1=zeros(NBNodes,1);
f2=zeros(NBNodes,1);
f3=zeros(NBNodes,1);
for i=1:NBElems
ML=zeros(3);
MGLSL=zeros(3);
f1L=zeros(3,1);
f2L=zeros(3,1);
f3L=zeros(3,1);
gx(1)=2./3.;
gx(2)=1./6.;
gx(3)=1./6.;
hx(1)=1./6.;
hx(2)=1./6.;
hx(3)=2./3.;
x1=Node(NLocal(NBelem(i,1)),1);
y1=Node(NLocal(NBelem(i,1)),2);
x2=Node(NLocal(NBelem(i,2)),1);
y2=Node(NLocal(NBelem(i,2)),2);
x3=Node(NLocal(NBelem(i,3)),1);
y3=Node(NLocal(NBelem(i,3)),2);
for j=1:3
g=gx(j);
h=hx(j);
phi(1)=1.-g-h;
phi(2)=g;
phi(3)=h;
phig(1)=-1.;
phig(2)=1.;
phig(3)=0.;
phih(1)=-1.;
phih(2)=0.;
phih(3)=1.;
djac=abs(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2));
for k=1:3
phix(k)=(1./djac)*((-y1+y3)*phig(k)+(y1-y2)*phih(k));
phiy(k)=(1./djac)*((x1-x3)*phig(k)+(-x1+x2)*phih(k));
end
delphi=[phix;phiy];
nodalLset=[LSetLocal(NBelem(i,1));LSetLocal(NBelem(i,2));LSetLocal(NBelem(i,3))];
nodalF=[F(NBelem(i,1));F(NBelem(i,2));F(NBelem(i,3))];
delset=delphi*nodalLset;
Floc=phi*nodalF;
ML=ML+(phi'*phi)/3.;
MGLSL=MGLSL+((delphi'*(delset/norm(delset)))*Floc*(charLen/abs(Floc)))*phi/3.;
f1L=f1L+phi'*Floc*norm(delset)/3.;
f2L=f2L+(delphi'*(delset/norm(delset))*Floc)*(charLen/abs(Floc))*Floc*norm(delset)/3.;
vs=charLen*((abs(visc+Floc*norm(delset)))/(norm(Floc*delset)+charLen));
f3L=f3L+vs*delphi'*delset/3.;
end
for k=1:3;
for j=1:3;
M(NBelem(i,j),NBelem(i,k))=M(NBelem(i,j),NBelem(i,k))+ML(j,k);
MGLS(NBelem(i,j),NBelem(i,k))=MGLS(NBelem(i,j),NBelem(i,k))+MGLSL(j,k);
end
f1(NBelem(i,k))=f1(NBelem(i,k))+f1L(k);
f2(NBelem(i,k))=f2(NBelem(i,k))+f2L(k);
f3(NBelem(i,k))=f3(NBelem(i,k))+f3L(k);
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Use Fast March Method to Reinitialize LS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function LSetLocal=fastMarch(LSetLocal,NBelem,Node,NLocal,NBNodes,NBElems)
newlSet=LSetLocal;
% Reinitialize LS
nstat=zeros(NBNodes,1);
for i=1:NBElems
for j=1:3
L(j)=sign(LSetLocal(NBelem(i,j)));
end
if L(1) ~= L(2) || L(1) ~= L(3)
for j=1:3
nstat(NBelem(i,j))=1;
end
end
end
maincheck=0;
while(maincheck==0)
lmin=1000.;
avlmin=1000.;
eindex=0;
nindex=0;
maincheck=1;
for i=1:NBElems
if nstat(NBelem(i,1))+nstat(NBelem(i,2))+nstat(NBelem(i,3))==2
maincheck=0;
check=0;
ltot=0.;
for j=1:3
if nstat(NBelem(i,j))==0
if abs(LSetLocal(NBelem(i,j)))<=lmin
check=1;
tempindex=j;
end
end
ltot=ltot+abs(LSetLocal(NBelem(i,j)));
end
if check==1 && ltot/3.<=avlmin
eindex=i;
nindex=tempindex;
lmin=LSetLocal(NBelem(eindex,nindex));
avlmin=ltot/3.;
end
end
end
if maincheck==0
% Find New LS for point
xp=Node(NLocal(NBelem(eindex,nindex)),1);
yp=Node(NLocal(NBelem(eindex,nindex)),2);
count=0;
for i=1:3
if i~=nindex
count=count+1;
x(count)=Node(NLocal(NBelem(eindex,i)),1);
y(count)=Node(NLocal(NBelem(eindex,i)),2);
lloc(count)=newlSet(NBelem(eindex,i));
end
end
delxa=x(1)-xp;
delya=y(1)-yp;
delxb=x(2)-xp;
delyb=y(2)-yp;
N=[delxa delya; delxb delyb];
M=N^-1;
A=(M(1)*M(1)+M(2)*M(2));
B=(M(3)*M(3)+M(4)*M(4));
C=2.*(M(1)*M(3)+M(2)*M(4));
a=A+B+C;
b=-2.*lloc(1)*A-2.*lloc(2)*B-C*(lloc(1)+lloc(2));
c=lloc(1)*lloc(1)*A+lloc(2)*lloc(2)*B+lloc(1)*lloc(2)*C-1.;
templ1=(-b+sqrt(b*b-4.*a*c))/(2.*a);
templ2=(-b-sqrt(b*b-4.*a*c))/(2.*a);
if abs(templ1)>abs(templ2)
newlSet(NBelem(eindex,nindex))=templ1;
else
newlSet(NBelem(eindex,nindex))=templ2;
end
nstat(NBelem(eindex,nindex))=1;
end
end
LSetLocal=newlSet;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Solve Implicit Porblem to Get Temperature
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Temp=getTemp(Node,Element,numNodes,numElem,LSet,Bound,Temp,Penalty,rho,dtImp,LSetOld)
K=zeros(numNodes*2,numNodes*2);
M=zeros(numNodes*2,numNodes*2);
MStar=zeros(numNodes*2,numNodes*2);
pforce=zeros(numNodes*2,1);
% Loop Through Elements
for e=1:numElem
Ke=zeros(8);
Me=zeros(8);
MeStar=zeros(8);
for icrd=1:4;
crdnx(icrd)=Node(Element(e,icrd),1);
crdny(icrd)=Node(Element(e,icrd),2);
theta(icrd)=LSet(Element(e,icrd));
thetaO(icrd)=LSetOld(Element(e,icrd));
end
check=0;
for i=1:3
for j=i+1:4
if sign(theta(1))~=sign(theta(j))
check=1;
end
end
end
if check==1
% 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);
phiO=phi;
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
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);
phiO=phi;
iLS=theta(1)*phi(1)+theta(2)*phi(3)+theta(3)*phi(5)+theta(4)*phi(7);
iLSO=thetaO(1)*phi(1)+thetaO(2)*phi(3)+thetaO(3)*phi(5)+thetaO(4)*phi(7);
if iLS<0.
cond=0.;
spec=0.01;
else
cond=1.;
spec=1.;
end
if iLSO<0.
specO=0.01;
else
specO=1.;
end
for iter=1:4
phi(2*iter)=phi(2*iter-1)*(abs(iLS)-abs(theta(iter)));
phiO(2*iter)=phiO(2*iter-1)*(abs(iLSO)-abs(thetaO(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)/dtImp)/double(enr);
MeStar=MeStar+((we*rho*specO*phi'*phiO)/dtImp)/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;
% pen=zeros(8);
% pfL=zeros(8,1);
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)+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)+1)=M(gnum(j)+1,gnum(i)+1)+Me(2*j,2*i);
MStar(gnum(j),gnum(i))=MStar(gnum(j),gnum(i))+MeStar(2*j-1,2*i-1);
MStar(gnum(j)+1,gnum(i)+1)=MStar(gnum(j)+1,gnum(i)+1)+MeStar(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)
RHS=MStar*Temp;
A=K+M;
Sub=A*Bound;
iindex=0;
for i=1:2*numNodes;
if Bound(i)==0.;
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i)+pforce(i);
jindex=0;
for j=1:2*numNodes;
if Bound(j)==0.;
jindex=jindex+1;
Ared(iindex,jindex)=A(i,j);
end
end
end
end
%Solve
Tempr=(Ared^-1)*RHSred';
iindex=0;
for i=1:2*numNodes;
if Bound(i)==0.;
iindex=iindex+1;
Temp(i)=Tempr(iindex);
end
end
Temp
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Generates the initial level set
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [LSet]=initialLSet(Node,numNodes)
%centx=4.;
%centy=4.;
%rad=2.1;
%for i=1:numNodes;
% dist=sqrt((Node(i,1)-centx)*(Node(i,1)-centx)+(Node(i,2)-centy)*(Node(i,2)-centy));
% LSet(i)=dist-rad;
%end
for i=1:numNodes;
dist=Node(i,1)-1.1;
LSet(i)=dist;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plot the level set
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function []=plotLSet(NumX,NumY,delX,delY,LSet)
[X Y]=meshgrid(0:delX:delX*NumX,0:delY:delY*NumY);
Z=zeros(NumX+1,NumY+1);
for i=1:(NumX+1)*(NumY+1)
Z(i)=LSet(i);
end
surf(X,Y,Z)
end

View file

@ -0,0 +1,801 @@
function []=XCOR_2D()
clear all
% Define Mesh
NumX=10;
NumY=1;
delX=1.;
delY=1.;
numElem=NumX*NumY;
numNodes=(NumX+1)*(NumY+1);
Elength=(delX+delY)/2.;
[Node,Element]=buildMesh(NumX,NumY,delX,delY);
% Simulation Parameters
rho=1.;
Penalty=200.;
dtImp=0.01;
dtExp=0.001;
tsteps=10;
bandWidth=10.;
epsilon=0.00001;
visc=0.0005;
% Get Initial Level Set
LSetOld=initialLSet(Node,numNodes);
% plotLSet(NumX,NumY,delX,delY,LSet);
% Initial Conditions
Temp=zeros(numNodes*2,1);
for i=1:numNodes
if LSetOld(i)<=0
Temp(2*i-1)=1.;
end
end
% Boundary Conditions
Bound=zeros(numNodes*2,1);
for i=1:numNodes
if Node(i,1)<delX/10.
Bound(2*i-1)=1.;
end
end
% Loop through time steps
for ts=1:tsteps
% Update Level Set
LSetNew=updateLSet(Temp,Node,numNodes,Element,numElem,dtImp,dtExp,LSetOld,...
Elength,bandWidth,epsilon,visc);
% Solve for Temperature
Temp=getTemp(Node,Element,numNodes,numElem,LSetNew,Bound,Temp,Penalty,rho,dtImp,LSetOld);
LSetOld=LSetNew;
LSetOld'
POUT(ts)=LSetOld(1);
end
POUT';
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create a linear quadrilateral FE mesh
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [Node,Element]=buildMesh(NumX,NumY,delX,delY)
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
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
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This function updates the level set
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [LSet]=updateLSet(Temp,Node,numNodes,Element,numElem,dtImp,dtExp,LSet,...
Elength,bandWidth,epsilon,visc)
% parameters
charLen=epsilon*Elength;
for tstep=1:floor(dtImp/dtExp)
% Identify Narrow Band Elements and Get Local Level Set
[NBelem,NBElems,NGlobal,NLocal,NBNodes,LSetLocal]=getNarrowBand(bandWidth,...
Elength,LSet,Element,numElem,numNodes);
% Identify Scalar Velocity on Nodes Crossed By Interface - F
F=getF(Temp,LSetLocal,NBElems,NBNodes,NLocal,NBelem,Node,Elength);
% Get 'Stiffness' Matrix - A
A=getA(Node,NLocal,NBelem,NBNodes,NBElems,LSetLocal);
% Apply BCs
RHS=-A*F;
iindex=0;
for i=1:NBNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i);
jindex=0;
for j=1:NBNodes
if F(j)==0.
jindex=jindex+1;
Ared(iindex,jindex)=A(i,j);
end
end
end
end
if iindex>0
% Solve for Fred
Fred=(Ared^-1)*RHSred';
% Get F
iindex=0;
for i=1:NBNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
end
% Get Level Set Equation Terms
[M,MGLS,f1,f2,f3]=getTerms(Node,NLocal,NBelem,NBNodes,NBElems,LSetLocal,visc,charLen,F);
LSetLocal=LSetLocal-((((M+MGLS)^-1)*dtExp)*(f1+f2+f3))';
% Reinitialize LS
%LSetLocal=fastMarch(LSetLocal,NBelem,Node,NLocal,NBNodes,NBElems);
for i=1:NBNodes
LSet(NLocal(i))=LSetLocal(i);
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Find elements in narrow band and create map between
% global node labels and those in narrow band
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [NBelem,NBElems,NGlobal,NLocal,NBNodes,LSetLocal]=getNarrowBand(bandWidth,...
ELength,LSet,Element,numElem,numNodes)
% Identify Narrow Band Elements
NBElems=0;
NBNodes=0;
NGlobal=zeros(numNodes);
for i=1:numElem
check=0;
for iNd=1:4
if abs(LSet(Element(i,iNd)))<=bandWidth*ELength
check=1;
end
end
% If an element is in the narrow band split it into triangles
if check==1
for j=1:4
if NGlobal(Element(i,j))==0
NBNodes=NBNodes+1;
NGlobal(Element(i,j))=NBNodes;
NLocal(NBNodes)=Element(i,j);
end
end
NBElems=NBElems+1;
NBelem(NBElems,1)=NGlobal(Element(i,1));
NBelem(NBElems,2)=NGlobal(Element(i,2));
NBelem(NBElems,3)=NGlobal(Element(i,3));
NBElems=NBElems+1;
NBelem(NBElems,1)=NGlobal(Element(i,1));
NBelem(NBElems,2)=NGlobal(Element(i,3));
NBelem(NBElems,3)=NGlobal(Element(i,4));
end
end
% Get local Level Set
for i=1:NBNodes
LSetLocal(i)=LSet(NLocal(i));
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Get Interface Normal Veloctiy 'F'
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function F=getF(Temp,LSetLocal,NBElems,NBNodes,NLocal,NBelem,Node,ELength)
F=zeros(NBNodes,1);
eStat=zeros(NBElems,1);
nData=zeros(NBNodes,2);
for i=1:NBElems
for j=1:3
L(j)=LSetLocal(NBelem(i,j));
end
x11=Node(NLocal(NBelem(i,1)),1);
x12=Node(NLocal(NBelem(i,2)),1);
x13=Node(NLocal(NBelem(i,3)),1);
y11=Node(NLocal(NBelem(i,1)),2);
y12=Node(NLocal(NBelem(i,2)),2);
y13=Node(NLocal(NBelem(i,3)),2);
count=0.;
if sign(L(1)) ~= sign(L(2))
eStat(i)=1;
count=count+1;
f=abs(L(1))/(abs(L(1))+abs(L(2)));
xi(count)=f*(x12-x11)+x11;
yi(count)=f*(y12-y11)+y11;
end
if sign(L(1)) ~= sign(L(3))
eStat(i)=1;
count=count+1;
f=abs(L(1))/(abs(L(1))+abs(L(3)));
xi(count)=f*(x13-x11)+x11;
yi(count)=f*(y13-y11)+y11 ;
end
if sign(L(2)) ~= sign(L(3))
eStat(i)=1;
count=count+1;
f=abs(L(2))/(abs(L(2))+abs(L(3)));
xi(count)=f*(x13-x12)+x12;
yi(count)=f*(y13-y12)+y12 ;
end
if eStat(i)==1
n=[yi(2)-yi(1); xi(1)-xi(2)];
n=n/norm(n);
xd(1,1)=(xi(1)+xi(2))/2.;
xd(1,2)=(yi(1)+yi(2))/2.;
xd(2,1)=0.15*ELength*n(1)+xd(1,1);
xd(2,2)=0.15*ELength*n(2)+xd(1,2);
% Check if xd2 is in element
v0(1)=x11;
v0(2)=y11;
v1(1)=x12-x11;
v1(2)=y12-y11;
v2(1)=x13-x11;
v2(2)=y13-y11;
v(1)=xd(2,1);
v(2)=xd(2,2);
ra=((v(1)*v2(2)-v2(1)*v(2))-(v0(1)*v2(2)-v2(1)*v0(2)))/(v1(1)*v2(2)-v2(1)*v1(2));
rb=-((v(1)*v1(2)-v1(1)*v(2))-(v0(1)*v1(2)-v1(1)*v0(2)))/(v1(1)*v2(2)-v2(1)*v1(2));
check=0;
if ra>0. && rb>0. && ra+rb<1.
index=i;
x21=x11;
x22=x12;
x23=x13;
y21=y11;
y22=y12;
y23=y13;
else
for j=1:NBElems
tx1=Node(NLocal(NBelem(j,1)),1);
tx2=Node(NLocal(NBelem(j,2)),1);
tx3=Node(NLocal(NBelem(j,3)),1);
ty1=Node(NLocal(NBelem(j,1)),2);
ty2=Node(NLocal(NBelem(j,2)),2);
ty3=Node(NLocal(NBelem(j,3)),2);
v0(1)=tx1;
v0(2)=ty1;
v1(1)=tx2-tx1;
v1(2)=ty2-ty1;
v2(1)=tx3-tx1;
v2(2)=ty3-ty1;
v(1)=xd(2,1);
v(2)=xd(2,2);
ra=((v(1)*v2(2)-v2(1)*v(2))-(v0(1)*v2(2)-v2(1)*v0(2)))/(v1(1)*v2(2)-v2(1)*v1(2));
rb=-((v(1)*v1(2)-v1(1)*v(2))-(v0(1)*v1(2)-v1(1)*v0(2)))/(v1(1)*v2(2)-v2(1)*v1(2));
if ra>0. && rb>0. && ra+rb<1.
index=j;
x21=tx1;
x22=tx2;
x23=tx3;
y21=ty1;
y22=ty2;
y23=ty3;
end
end
end
Ae=0.5*((x12*y13-x13*y12)+(y12-y13)*x11+(x13-x12)*y11);
N1=(1./(2.*Ae))*((y12-y13)*(xd(1,1)-x12)+(x13-x12)*(xd(1,2)-y12));
N2=(1./(2.*Ae))*((y13-y11)*(xd(1,1)-x13)+(x11-x13)*(xd(1,2)-y13));
N3=(1./(2.*Ae))*((y11-y12)*(xd(1,1)-x11)+(x12-x11)*(xd(1,2)-y11));
T1=Temp(2*NLocal(NBelem(i,1))-1);
T2=Temp(2*NLocal(NBelem(i,2))-1);
T3=Temp(2*NLocal(NBelem(i,3))-1);
a1=Temp(2*NLocal(NBelem(i,1)));
a2=Temp(2*NLocal(NBelem(i,2)));
a3=Temp(2*NLocal(NBelem(i,3)));
L1=LSetLocal(NBelem(i,1));
L2=LSetLocal(NBelem(i,2));
L3=LSetLocal(NBelem(i,3));
LS=abs(N1*L1+L2*N2+L3*N3);
p1=N1*(LS-abs(L1));
p2=N2*(LS-abs(L2));
p3=N3*(LS-abs(L3));
T(1)=N1*T1+N2*T2+N3*T3+p1*a1+p2*a2+p3*a3;
Ae=0.5*((x22*y23-x23*y22)+(y22-y23)*x21+(x23-x22)*y21);
N1=(1./(2.*Ae))*((y22-y23)*(xd(2,1)-x22)+(x23-x22)*(xd(2,2)-y22));
N2=(1./(2.*Ae))*((y23-y21)*(xd(2,1)-x23)+(x21-x23)*(xd(2,2)-y23));
N3=(1./(2.*Ae))*((y21-y22)*(xd(2,1)-x21)+(x22-x21)*(xd(2,2)-y21));
T1=Temp(2*NLocal(NBelem(index,1))-1);
T2=Temp(2*NLocal(NBelem(index,2))-1);
T3=Temp(2*NLocal(NBelem(index,3))-1);
a1=Temp(2*NLocal(NBelem(index,1)));
a2=Temp(2*NLocal(NBelem(index,2)));
a3=Temp(2*NLocal(NBelem(index,3)));
L1=LSetLocal(NBelem(index,1));
L2=LSetLocal(NBelem(index,2));
L3=LSetLocal(NBelem(index,3));
LS=abs(N1*L1+L2*N2+L3*N3);
p1=N1*(LS-abs(L1));
p2=N2*(LS-abs(L2));
p3=N3*(LS-abs(L3));
T(2)=N1*T1+N2*T2+N3*T3+p1*a1+p2*a2+p3*a3
gradT=(T(2)-T(1))/(0.15*ELength);
for j=1:3
nData(NBelem(i,j),1)=nData(NBelem(i,j),1)+1.;
nData(NBelem(i,j),2)=nData(NBelem(i,j),2)+0.1*gradT;
end
end
end
for i=1:NBNodes
if nData(i,1)>0
F(i)=nData(i,2)/nData(i,1);
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Get 'Stiffness' Matrix 'A'
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [A]=getA(Node,NLocal,NBelem,NBNodes,NBElems,LSetLocal)
A=zeros(NBNodes);
for i=1:NBElems
gx(1)=2./3.;
gx(2)=1./6.;
gx(3)=1./6.;
hx(1)=1./6.;
hx(2)=1./6.;
hx(3)=2./3.;
AfL=zeros(3);
AfLGLS=zeros(3);
x1=Node(NLocal(NBelem(i,1)),1);
y1=Node(NLocal(NBelem(i,1)),2);
x2=Node(NLocal(NBelem(i,2)),1);
y2=Node(NLocal(NBelem(i,2)),2);
x3=Node(NLocal(NBelem(i,3)),1);
y3=Node(NLocal(NBelem(i,3)),2);
for j=1:3
g=gx(j);
h=hx(j);
phi(1)=1.-g-h;
phi(2)=g;
phi(3)=h;
phig(1)=-1.;
phig(2)=1.;
phig(3)=0.;
phih(1)=-1.;
phih(2)=0.;
phih(3)=1.;
djac=2*abs(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2));
for k=1:3
phix(k)=(1./djac)*((-y1+y3)*phig(k)+(y1-y2)*phih(k));
phiy(k)=(1./djac)*((x1-x3)*phig(k)+(-x1+x2)*phih(k));
end
delphi=[phix;phiy];
nodalLset=[LSetLocal(NBelem(i,1));LSetLocal(NBelem(i,2));LSetLocal(NBelem(i,3))];
set=phi*nodalLset;
delset=delphi*nodalLset;
AfL=AfL+(phi'*sign(set))*(delset'*delphi)/3.;
AfLGLS=AfLGLS+(delphi'*delset)*(1./norm(delset))*(delset'*delphi)/3.;
end
sum=AfL+AfLGLS;
for k=1:3;
for j=1:3;
A(NBelem(i,j),NBelem(i,k))=A(NBelem(i,j),NBelem(i,k))+sum(j,k);
end
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Get terms for LS equation
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [M,MGLS,f1,f2,f3]=getTerms(Node,NLocal,NBelem,NBNodes,NBElems,LSetLocal,visc,charLen,F)
M=zeros(NBNodes);
MGLS=zeros(NBNodes);
f1=zeros(NBNodes,1);
f2=zeros(NBNodes,1);
f3=zeros(NBNodes,1);
for i=1:NBElems
ML=zeros(3);
MGLSL=zeros(3);
f1L=zeros(3,1);
f2L=zeros(3,1);
f3L=zeros(3,1);
gx(1)=2./3.;
gx(2)=1./6.;
gx(3)=1./6.;
hx(1)=1./6.;
hx(2)=1./6.;
hx(3)=2./3.;
x1=Node(NLocal(NBelem(i,1)),1);
y1=Node(NLocal(NBelem(i,1)),2);
x2=Node(NLocal(NBelem(i,2)),1);
y2=Node(NLocal(NBelem(i,2)),2);
x3=Node(NLocal(NBelem(i,3)),1);
y3=Node(NLocal(NBelem(i,3)),2);
for j=1:3
g=gx(j);
h=hx(j);
phi(1)=1.-g-h;
phi(2)=g;
phi(3)=h;
phig(1)=-1.;
phig(2)=1.;
phig(3)=0.;
phih(1)=-1.;
phih(2)=0.;
phih(3)=1.;
djac=abs(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2));
for k=1:3
phix(k)=(1./djac)*((-y1+y3)*phig(k)+(y1-y2)*phih(k));
phiy(k)=(1./djac)*((x1-x3)*phig(k)+(-x1+x2)*phih(k));
end
delphi=[phix;phiy];
nodalLset=[LSetLocal(NBelem(i,1));LSetLocal(NBelem(i,2));LSetLocal(NBelem(i,3))];
nodalF=[F(NBelem(i,1));F(NBelem(i,2));F(NBelem(i,3))];
delset=delphi*nodalLset;
Floc=phi*nodalF;
ML=ML+(phi'*phi)/3.;
MGLSL=MGLSL+((delphi'*(delset/norm(delset)))*Floc*(charLen/abs(Floc)))*phi/3.;
f1L=f1L+phi'*Floc*norm(delset)/3.;
f2L=f2L+(delphi'*(delset/norm(delset))*Floc)*(charLen/abs(Floc))*Floc*norm(delset)/3.;
vs=charLen*((abs(visc+Floc*norm(delset)))/(norm(Floc*delset)+charLen));
f3L=f3L+vs*delphi'*delset/3.;
end
for k=1:3;
for j=1:3;
M(NBelem(i,j),NBelem(i,k))=M(NBelem(i,j),NBelem(i,k))+ML(j,k);
MGLS(NBelem(i,j),NBelem(i,k))=MGLS(NBelem(i,j),NBelem(i,k))+MGLSL(j,k);
end
f1(NBelem(i,k))=f1(NBelem(i,k))+f1L(k);
f2(NBelem(i,k))=f2(NBelem(i,k))+f2L(k);
f3(NBelem(i,k))=f3(NBelem(i,k))+f3L(k);
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Use Fast March Method to Reinitialize LS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function LSetLocal=fastMarch(LSetLocal,NBelem,Node,NLocal,NBNodes,NBElems)
newlSet=LSetLocal;
% Reinitialize LS
nstat=zeros(NBNodes,1);
for i=1:NBElems
for j=1:3
L(j)=sign(LSetLocal(NBelem(i,j)));
end
if L(1) ~= L(2) || L(1) ~= L(3)
for j=1:3
nstat(NBelem(i,j))=1;
end
end
end
maincheck=0;
while(maincheck==0)
lmin=1000.;
avlmin=1000.;
eindex=0;
nindex=0;
maincheck=1;
for i=1:NBElems
if nstat(NBelem(i,1))+nstat(NBelem(i,2))+nstat(NBelem(i,3))==2
maincheck=0;
check=0;
ltot=0.;
for j=1:3
if nstat(NBelem(i,j))==0
if abs(LSetLocal(NBelem(i,j)))<=lmin
check=1;
tempindex=j;
end
end
ltot=ltot+abs(LSetLocal(NBelem(i,j)));
end
if check==1 && ltot/3.<=avlmin
eindex=i;
nindex=tempindex;
lmin=LSetLocal(NBelem(eindex,nindex));
avlmin=ltot/3.;
end
end
end
if maincheck==0
% Find New LS for point
xp=Node(NLocal(NBelem(eindex,nindex)),1);
yp=Node(NLocal(NBelem(eindex,nindex)),2);
count=0;
for i=1:3
if i~=nindex
count=count+1;
x(count)=Node(NLocal(NBelem(eindex,i)),1);
y(count)=Node(NLocal(NBelem(eindex,i)),2);
lloc(count)=newlSet(NBelem(eindex,i));
end
end
delxa=x(1)-xp;
delya=y(1)-yp;
delxb=x(2)-xp;
delyb=y(2)-yp;
N=[delxa delya; delxb delyb];
M=N^-1;
A=(M(1)*M(1)+M(2)*M(2));
B=(M(3)*M(3)+M(4)*M(4));
C=2.*(M(1)*M(3)+M(2)*M(4));
a=A+B+C;
b=-2.*lloc(1)*A-2.*lloc(2)*B-C*(lloc(1)+lloc(2));
c=lloc(1)*lloc(1)*A+lloc(2)*lloc(2)*B+lloc(1)*lloc(2)*C-1.;
templ1=(-b+sqrt(b*b-4.*a*c))/(2.*a);
templ2=(-b-sqrt(b*b-4.*a*c))/(2.*a);
if abs(templ1)>abs(templ2)
newlSet(NBelem(eindex,nindex))=templ1;
else
newlSet(NBelem(eindex,nindex))=templ2;
end
nstat(NBelem(eindex,nindex))=1;
end
end
LSetLocal=newlSet;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Solve Implicit Porblem to Get Temperature
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function Temp=getTemp(Node,Element,numNodes,numElem,LSet,Bound,Temp,Penalty,rho,dtImp,LSetOld)
K=zeros(numNodes*2,numNodes*2);
M=zeros(numNodes*2,numNodes*2);
MStar=zeros(numNodes*2,numNodes*2);
pforce=zeros(numNodes*2,1);
% Loop Through Elements
for e=1:numElem
Ke=zeros(8);
Me=zeros(8);
MeStar=zeros(8);
for icrd=1:4;
crdnx(icrd)=Node(Element(e,icrd),1);
crdny(icrd)=Node(Element(e,icrd),2);
theta(icrd)=LSet(Element(e,icrd));
thetaO(icrd)=LSetOld(Element(e,icrd));
end
check=0;
for i=1:3
for j=i+1:4
if sign(theta(1))~=sign(theta(j))
check=1;
end
end
end
if check==1
% 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);
phiO=phi;
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
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);
phiO=phi;
iLS=theta(1)*phi(1)+theta(2)*phi(3)+theta(3)*phi(5)+theta(4)*phi(7);
iLSO=thetaO(1)*phi(1)+thetaO(2)*phi(3)+thetaO(3)*phi(5)+thetaO(4)*phi(7);
if iLS<0.
cond=0.;
spec=0.01;
else
cond=1.;
spec=1.;
end
if iLSO<0.
specO=0.01;
else
specO=1.;
end
for iter=1:4
phi(2*iter)=phi(2*iter-1)*(abs(iLS)-abs(theta(iter)));
phiO(2*iter)=phiO(2*iter-1)*(abs(iLSO)-abs(thetaO(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)/dtImp)/double(enr);
MeStar=MeStar+((we*rho*specO*phi'*phiO)/dtImp)/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;
% pen=zeros(8);
% pfL=zeros(8,1);
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)+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)+1)=M(gnum(j)+1,gnum(i)+1)+Me(2*j,2*i);
MStar(gnum(j),gnum(i))=MStar(gnum(j),gnum(i))+MeStar(2*j-1,2*i-1);
MStar(gnum(j)+1,gnum(i)+1)=MStar(gnum(j)+1,gnum(i)+1)+MeStar(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)
RHS=MStar*Temp;
A=K+M;
Sub=A*Bound;
iindex=0;
for i=1:2*numNodes;
if Bound(i)==0.;
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i)+pforce(i);
jindex=0;
for j=1:2*numNodes;
if Bound(j)==0.;
jindex=jindex+1;
Ared(iindex,jindex)=A(i,j);
end
end
end
end
%Solve
Tempr=(Ared^-1)*RHSred';
iindex=0;
for i=1:2*numNodes;
if Bound(i)==0.;
iindex=iindex+1;
Temp(i)=Tempr(iindex);
end
end
Temp
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Generates the initial level set
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [LSet]=initialLSet(Node,numNodes)
%centx=4.;
%centy=4.;
%rad=2.1;
%for i=1:numNodes;
% dist=sqrt((Node(i,1)-centx)*(Node(i,1)-centx)+(Node(i,2)-centy)*(Node(i,2)-centy));
% LSet(i)=dist-rad;
%end
for i=1:numNodes;
dist=Node(i,1)-4.6;
LSet(i)=dist;
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plot the level set
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function []=plotLSet(NumX,NumY,delX,delY,LSet)
[X Y]=meshgrid(0:delX:delX*NumX,0:delY:delY*NumY);
Z=zeros(NumX+1,NumY+1);
for i=1:(NumX+1)*(NumY+1)
Z(i)=LSet(i);
end
surf(X,Y,Z)
end

View file

@ -0,0 +1,62 @@
*HEADING
Test for passing abaqus material to UELMAT: transient heat transfer
*RESTART,WRITE,NUMBER INTERVAL=10
*PREPRINT,MODEL=YES
*PART,NAME=part1
*NODE,NSET=NALL
1,0,0,0
2,1,0,0
3,0,1,0
4,1,1,0
5,0,2,0
6,1,2,0
*NSET,NSET=Left
1,3,5
*NSET,NSET=Right
2,4,6
*USER ELEMENT, TYPE=U1, NODES=4, COORDINATES=2,
INTEGRATION=4,TENSOR=TWOD
11,
*ELEMENT,TYPE=U1,ELSET=SOLID
1, 1,2,4,3
2, 3,4,6,5
*END PART
*ASSEMBLY,NAME=A1
*INSTANCE,NAME=I1,PART=PART1
*END INSTANCE
*Nset, nset=Set-6, instance=I1
1,3,5
*Nset, nset=Set-7, instance=I1
2,4,6
*END ASSEMBLY
*UEL PROPERTY, ELSET=I1.SOLID, MATERIAL=MAT_THERM
**************************************
***************************************
*MATERIAL,NAME=MAT_THERM
*CONDUCTIVITY
1.0,
*SPECIFIC HEAT
1.,
*DENSITY
1.,
*Initial Conditions, type=TEMPERATURE
Set-6, 1.,0.
*Initial Conditions, type=TEMPERATURE
Set-7, 0.,0.
*STEP
*HEAT TRANSFER, DELTMX=1.
0.1,1.0,,0.1
**
*BOUNDARY
Set-6,11,11,1.
*OUTPUT,FIELD,freq=1
*ELEMENT OUTPUT,ELSET=I1.SOLID
HFL,
*NODE OUTPUT,NSET=I1.NALL
NT,
*OUTPUT,HISTORY
*ELEMENT OUTPUT,ELSET=I1.SOLID
HFL,
*NODE OUTPUT,NSET=I1.NALL
NT11,
*END STEP