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,31 @@
# Python Preprocessor Script for Abaqus Corrosion Model
# J. Grogan, D. Gastaldi - Created. 19-07-11
# Import abaqus modules
from abaqusConstants import *
from abaqus import *
import random
# Create Model, Assembly and Instance objects
modelNames=mdb.models.keys()
corModel=mdb.models[modelNames[0]]
corAssembly=corModel.rootAssembly
corSurf=corAssembly.surfaces['Corrode']
surfFaces=corSurf.faces
incFile=open('CorSurf.dat','w')
for i in range(0,len(surfFaces)):
eachFace=surfFaces[i]
elemFaces=eachFace.getElementFaces()
for j in range(0,len(elemFaces)):
eachElemFace=elemFaces[j]
faceNodes=eachElemFace.getNodes()
centx=0.
centy=0.
centz=0.
for k in range(0,len(faceNodes)):
centx=centx+faceNodes[k].coordinates[0]
centy=centy+faceNodes[k].coordinates[1]
centz=centz+faceNodes[k].coordinates[2]
centx=centx/float(len(faceNodes))
centy=centy/float(len(faceNodes))
centz=centz/float(len(faceNodes))
incFile.write ("%f %f %f \n"%(centx,centy,centz))
incFile.close()

View file

@ -0,0 +1,193 @@
! This program generates a micro-strucutre mask and applies it to
! an existing mesh.
! J.Grogan 05/08/11
program Voronoi3DPost
!
! Parameters
parameter(max_elements=100000,max_cells=20000,max_fc=100)
parameter(max_elem_in_cell=50000,max_neigh_per_elem=6,max_neighbours=50)
!
! Variables
character(len=256)input
character(len=256)input2(2)
integer num_neighbours(100000),neighbour(100000,max_neighbours)
real nbr_dist(100000,max_neighbours)
real cor_faces(100000,3),cor_dist(100000)
double precision,allocatable,dimension(:,:)::ele_centroid
!
allocate(ele_centroid(max_elements,3))
mesh_type=3
call elem_centroids(num_elements,ele_centroid,mesh_type)
rmax_dist=0.020
neighbour=0
!
! Get neighbouring elements
do i=1,num_elements
icount=1
do j=1,num_elements
if(icount>max_neighbours)then
rmaxdist=0.
do k=1,max_neighbours
if(nbr_dist(i,k)>rmaxdist)then
rmaxdist=nbr_dist(i,k)
index_max_dist=k
endif
enddo
endif
cent1x=ele_centroid(i,1)
cent1y=ele_centroid(i,2)
cent1z=ele_centroid(i,3)
cent2x=ele_centroid(j,1)
cent2y=ele_centroid(j,2)
cent2z=ele_centroid(j,3)
dist=sqrt((cent1x-cent2x)*(cent1x-cent2x)+(cent1y-cent2y)*(cent1y-cent2y)&
&+(cent1z-cent2z)*(cent1z-cent2z))
if(icount>max_neighbours)then
if(dist<rmaxdist)then
nbr_dist(i,index_max_dist)=dist
neighbour(i,index_max_dist)=j
endif
else
nbr_dist(i,j)=dist
neighbour(i,j)=j
endif
icount=icount+1
enddo
! print *,float(i)/float(num_elements)
enddo
!
! Get corrosion surface distances
open(unit=20,file='CorSurf.dat',status='unknown')
read(20,*)num_faces
ierr=0
num_faces=1
do while (ierr==0)
read(20,*,iostat=ierr)cor_faces(num_faces,1),cor_faces(num_faces,2),&
&cor_faces(num_faces,3)
if(ierr==0)num_faces=num_faces+1
enddo
close(unit=20)
do i=1,num_elements
centx=ele_centroid(i,1)
centy=ele_centroid(i,2)
centz=ele_centroid(i,3)
distmin=1000.
do j=1,num_faces-1
facex=cor_faces(j,1)
facey=cor_faces(j,2)
facez=cor_faces(j,3)
dist=sqrt((centx-facex)*(centx-facex)+(centy-facey)*(centy-facey)&
&+(centz-facez)*(centz-facez))
if(dist<distmin)distmin=dist
enddo
cor_dist(i)=distmin
enddo
! Write New Input File
rewind(10)
open(unit=13,file='Corrosion.inp',status='unknown')
input2(1)='**'
do while (index(input2(1),'*End Assembly')==0)
read(10,'(a)')input2(2)
write(13,'(a)')input2(1)
input2(1)=input2(2)
enddo
write(13,'(a)')'*End Assembly'
write(13,*)'*INITIAL CONDITIONS,TYPE=SOLUTION'
do i=1,num_elements
write(13,'(3(a,i6),2(a,f18.6),3(i6,a))')'Assembly.CorPart.',i,',',i,',',&
& max_neighbours,',',0.,',',cor_dist(i),0,',',0,',',0,','
write(13,'(8(i6,a))')0,',',0,',',0,',',0,',',0,',',0,',',0,',',1,','
do j=1, max_neighbours
if(mod(j,8)/=0)then
if(j/=max_neighbours)then
write(13,'(i6,a)',advance='no')neighbour(i,j),','
else
write(13,'(i6)')neighbour(i,j)
endif
else
if(j/=max_neighbours)then
write(13,'(i6,a)')neighbour(i,j),','
else
write(13,'(i6)')neighbour(i,j)
endif
endif
enddo
enddo
ierr=0
do while (ierr==0)
read(10,'(a)',iostat=ierr)input2(1)
if(ierr==0)write(13,'(a)')input2(1)
enddo
end program
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Get Element Centroids
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine elem_centroids(ne,ele_centroid,mesh_type)
!
! Parameters
parameter(max_nodes=1000000,max_elements=100000,max_node_in_elem=8)
!
! Variables
character(len=256)input
integer,dimension(max_elements,max_node_in_elem)::elements
double precision,dimension(max_nodes,3)::nodes
double precision,dimension(max_elements,3)::ele_centroid
!
! Open Input File and read node and element co-ordinates
open(unit=10,file='Corrosion_Temp.inp',status='unknown')
do while (index(input,'*Node')==0)
read(10,'(a)')input
end do
nn=0
do while(1==1)
read(10,'(a)')input
if(index(input,'*')==0)then
backspace(10)
nn=nn+1
if(mesh_type==3)then
read(10,*)dummy,nodes(nn,1),nodes(nn,2),nodes(nn,3)
else
read(10,*)dummy,nodes(nn,1),nodes(nn,2)
endif
else
if(mesh_type==2)then
nele_type=4
else
if(index(input,'C3D8')/=0)nele_type=8
if(index(input,'C3D4')/=0)nele_type=4
endif
exit
endif
end do
ne=0
do while(1==1)
read(10,'(a)')input
if(index(input,'*')==0)then
backspace(10)
ne=ne+1
if(nele_type==8)then
read(10,*)dummy,elements(ne,1),elements(ne,2),elements(ne,3),elements(ne,4)&
& ,elements(ne,5),elements(ne,6),elements(ne,7),elements(ne,8)
elseif(nele_type==4)then
read(10,*)dummy,elements(ne,1),elements(ne,2),elements(ne,3),elements(ne,4)
endif
else
exit
endif
end do
!
! Get element centroid
do i=1,ne
centroidx=0.d0
centroidy=0.d0
centroidz=0.d0
do j=1,nele_type
centroidx=centroidx+nodes(elements(i,j),1)
centroidy=centroidy+nodes(elements(i,j),2)
if(mesh_type==3)centroidz=centroidz+nodes(elements(i,j),3)
enddo
ele_centroid(i,1)=centroidx/float(nele_type)
ele_centroid(i,2)=centroidy/float(nele_type)
if(mesh_type==3)ele_centroid(i,3)=centroidz/float(nele_type)
enddo
end subroutine

View file

@ -0,0 +1,164 @@
# GrainGen V2.0
# This script generates idealised and representative meshed micro-structure geometries
# in 2-D and 3-D through the Abaqus geometry kernel. - J. Grogan, 09/06/2011
#
# Import Abaqus and External Modules
from abaqusConstants import *
from abaqus import *
import random
import subprocess
import regionToolset
import mesh
import step
import part
import interaction
import GeomModules
#
# Create Model Database
VerFile=Mdb(pathName="MStructure")
VerModel=VerFile.models['Model-1']
VerAssembly=VerModel.rootAssembly
#
# Assign Model Parameters
shape=4 # 1 - Square, 2- Hex, 3 -Dodec, 4- Voronoi
part_type=2 # 2 - Shell, 3 - Solid
dimension=2 # 2 - 2D, 3 - 3D
rad=0.00595 # Characteristic Dimension (except Voronoi)
meshsize=0.0005 # Global Mesh Seed Size
num_high=16 # Number of Grains in X-Dir
num_wide=6 # Number of Grains in Y-Dir
num_thick=1 # Number of Grains in Z-Dir
num_grains=25 # Target Number of Grains (Voronoi Only)
scalex=1. # Voronoi Part Scale X-Dir (Voronoi Only)
scaley=3.5 # Voronoi Part Scale Y-Dir (Voronoi Only)
scalez=1. # Voronoi Part Scale Z-Dir (Voronoi Only)
ana_type=1 # 1 - Crystal Plasticity, 2 - Corrosion
hard_rad=0.0 # Hardcore voronoi min. radius (Voronoi Only)
random_seed=92271 # Random seed for voronoi grain generation or random vector generation
#
# Choose Script Function - Set to 1 to activate
assemble_grains = 1 # Assemble Multiple Grains and Merge Them
boolean_cut = 1 # Perform Boolean Cut Operation
mesh_part = 1 # Mesh the Final Geometry
mat_props = 1 # Assign Material Properties
bound_conds = 1 # Generate steps and apply BCs
write_output =1 # Write Output File
post_proc = 0 # Postprocess INP file (Corrosion Only)
#
# For 2-D Solids thickness is set equal to one element
if dimension==3:
extrude_depth=rad
else:
extrude_depth=meshsize
num_thick=1
#
# Draw a Square Grain
if shape==1:
GeomModules.DrawSquare(VerModel,part_type,rad,extrude_depth)
#
# Draw a Hexagonal Grain
if shape==2:
GeomModules.DrawHexagon(VerModel,part_type,rad,extrude_depth)
#
# Draw a Dodecahedral Grain
if shape==3:
GeomModules.DrawDodec(VerModel,rad)
#
# Draw a Voronoi Tessellation
if shape==4:
if dimension==2:
maxsize=max(scalex,scaley)
GeomModules.Voronoi2D(VerModel,part_type,extrude_depth,num_grains,maxsize,hard_rad,random_seed)
else:
maxsize=max(scalex,scaley,scalez)
GeomModules.Voronoi3D(VerModel,num_grains,maxsize,hard_rad,random_seed)
#
# Assemble Base Parts
if assemble_grains==1:
if shape<=3:
VerPart=VerModel.parts['Base']
GeomModules.PatternParts(num_high,num_wide,num_thick,VerPart,rad,shape,VerModel)
#
# Make a Boolean Template
if boolean_cut==1:
if shape>1:
GeomModules.BooleanPart(VerModel,part_type,rad,extrude_depth,num_high,
num_wide,num_thick,shape,dimension,scalex,scaley,scalez)
BoolPart=VerModel.parts['Template']
#
#Perform Boolean Cut
if shape==1:
VerPart=VerModel.parts['Merged']
del VerAssembly.instances['Merged-1']
else:
VerAssembly.InstanceFromBooleanCut(name='FinalPart',
instanceToBeCut=VerAssembly.instances['Merged-1'],
cuttingInstances=(VerAssembly.instances['Template-1'], ),
originalInstances=DELETE)
del VerAssembly.instances['FinalPart-1']
VerPart=VerModel.parts['FinalPart']
#
# Mesh Part
if mesh_part==1:
if shape<3:
VerPart.setMeshControls(regions=VerPart.cells, elemShape=HEX, technique=STRUCTURED)
if shape==3:
VerPart.setMeshControls(regions=VerPart.cells, elemShape=TET, technique=FREE)
if shape==4:
if dimension==2:
VerPart.setMeshControls(regions=VerPart.cells, elemShape=HEX, technique=SWEEP,
algorithm=ADVANCING_FRONT)
else:
VerPart.setMeshControls(regions=VerPart.cells, elemShape=TET, technique=FREE)
VerPart.seedPart(size=meshsize)
VerPart.generateMesh()
#
# For Corrosion Analysis Output Part Vertices and Element Connectivity
if ana_type==2:
GeomModules.VertsConn(VerPart,dimension)
ecor=open('ecor.dat','w')
for eachface in VerPart.faces:
if len(eachface.getAdjacentFaces())<7.:
xnor=eachface.getNormal()[0]
ynor=eachface.getNormal()[1]
znor=eachface.getNormal()[2]
if (xnor==0.)and(znor==0.):
# if (ynor==1.)or(ynor==-1.):
if (ynor==1.):
ecor.write("%6.4f %6.4f %6.4f\n"%(xnor,ynor,znor))
ecor.close()
#
#Generate Materials and Sections
if mat_props==1:
GeomModules.MatGen(ana_type,VerPart,VerModel,part_type,meshsize,random_seed)
#
#Steps and Boundary Conditions
if bound_conds==1:
VerModel.ExplicitDynamicsStep(name='Corrode', previous='Initial',
massScaling=((SEMI_AUTOMATIC, MODEL, AT_BEGINNING, 0.0, 1e-06,
BELOW_MIN, 0, 0, 0.0, 0.0, 0, None), ))
VerModel.ExplicitDynamicsStep(name='Load', previous='Corrode',
timePeriod=1.)
VerModel.steps['Corrode'].Restart(numberIntervals=2,overlay=OFF,timeMarks=OFF)
VerModel.steps['Load'].Restart(numberIntervals=2,overlay=OFF, timeMarks=OFF)
VerModel.FieldOutputRequest(name='F-Output-1',
createStepName='Corrode', variables=('A', 'CSTRESS', 'LE', 'PE',
'PEEQ', 'RF', 'S', 'SDV', 'STATUS', 'U','V'), numIntervals=100)
#
#Loads and BCs
VerAssembly.Instance(name='CorPart',part=VerPart, dependent=ON)
iNodes=VerAssembly.instances['CorPart'].nodes
# GeomModules.S1BCs(iNodes,VerModel,num_high,num_wide,num_thick,shape,
# dimension,extrude_depth,rad,scalex,scaley,scalez)
#
#VerAssembly.Instance(name='CorPart',part=VerPart, dependent=ON)
#Create Job and write input file
if write_output ==1:
VerFile.Job(name='GeomGenTemp', model='Model-1', type=ANALYSIS,
explicitPrecision=SINGLE, nodalOutputPrecision=SINGLE,userSubroutine='',
parallelizationMethodExplicit=DOMAIN,numDomains=1,multiprocessingMode=DEFAULT, numCpus=1)
VerFile.jobs['GeomGenTemp'].writeInput(consistencyChecking=OFF)
#
# Perform Postprocessing for corrosion analysis
if post_proc ==1:
retcode=subprocess.call("GeomGenPost2.exe")

View file

@ -0,0 +1,173 @@
!This program calculates the distance from each element
!to its nearest grain boundary
Program GeomConnectivity
!
! Parameters
parameter(max_nodes=1000000,max_elements=1000000,max_node_in_elem=8)
parameter(max_cells=1000,max_elem_in_cell=10000,max_neigh_per_elem=6)
parameter(max_faces_in_cell=100)
!
! Declare Variables
character*256 input,input2(2)
integer elements(max_elements,max_node_in_element)
integer active(max_elements)
integer num_elements(max_cells)
integer elem_label=(max_cells,max_elem_in_cell)
integer num_neighbours=(max_cells,max_elem_in_cell)
integer elem_neighbours=(max_cells,max_elem_in_cell,max_neigh_per_elem)
integer num_faces(max_cells)
real nodes(max_nodes,3)
real face_coords(max_cells,max_faces_in_cell,9)
real dotprod(max_node_in_element,max_faces_in_cell)
real average(max_faces_in_cell)
real distance(max_cells,max_elem_in_cell)
!
! Initialise Variables
nodes=0.
face_coords=0.
dotprod=0.
average=0.
distance=0.
elements=0
active=0
num_elements=0
elem_label=0
num_neighbours=0
elem_neighbours=0
num_faces=0
!
! Open Input File and read node and element co-ordinates
open(unit=10,file='GeomGenTemp.inp',status='unknown')
do while (index(input,'*Node')==0)
read(10,'(a)')input
end do
nn=0
do while(1==1)
read(10,'(a)')input
if(index(input,'*')==0)then
backspace(10)
nn=nn+1
read(10,*)nodes(nn,1),nodes(nn,2),nodes(nn,3)
else
exit
endif
end do
ne=0
do while(1==1)
read(10,'(a)')input
if(index(input,'*')==0)then
backspace(10)
ne=ne+1
read(10,*)dummy,elements(ne,1),elements(ne,2),elements(ne,3),elements(ne,4)&
& ,elements(ne,5),elements(ne,6),elements(ne,7),elements(ne,8)
else
exit
endif
end do
!
! Open GeomGen output file and read element connectivity, cell, face and
! vertice data.
open(unit=11,file='vertout.dat',status='old')
read(11,*)idimension
read(11,*)num_cells
do i=1,num_cells
read(11,*)num_elements(i)
do j=1,num_elements(i)
read(11,*)elem_label(i,j)
read(11,*)num_neighbours(i,j)
do k=1,num_neighbours(i,j)
read(11,*)elem_neighbours(i,j,k)
enddo
enddo
read(11,*)num_faces(i)
do j=1,num_faces(i)
read(11,*)face_coords(i,j,1),face_coords(i,j,2),face_coords(i,j,3)
read(11,*)face_coords(i,j,4),face_coords(i,j,5),face_coords(i,j,6)
read(11,*)face_coords(i,j,7),face_coords(i,j,8),face_coords(i,j,9)
enddo
enddo
!
! Determine normal distance between element centroid and closest face
do i=1,num_cells
do j=1,num_elements(i)
do k=1,8
nodex=nodes(elements(elem_label(i,j),k),1)
nodey=nodes(elements(elem_label(i,j),k),2)
nodez=nodes(elements(elem_label(i,j),k),3)
do m=1,num_faces(i)
vert1x=face_coords(i,m,1)
vert1y=face_coords(i,m,1)
vert1z=face_coords(i,m,1)
vert2x=face_coords(i,m,2)
vert2y=face_coords(i,m,2)
vert2z=face_coords(i,m,2)
vert3x=face_coords(i,m,3)
vert3y=face_coords(i,m,3)
vert3z=face_coords(i,m,3)
v1v2i=vert1x-vert2x
v1v2j=vert1y-vert2y
v1v2k=vert1z-vert2z
v1v3i=vert1x-vert3x
v1v3j=vert1y-vert3y
v1v3k=vert1z-vert3z
v1ni=vert1x-nodex
v1nj=vert1y-nodey
v1nk=vert1z-nodez
crossi=v1v2j*v1v3k-v1v2k*v1v3j
crossj=v1v2k*v1v3i-v1v2i*v1v3k
crossk=v1v2i*v1v3j-v1v2j*v1v3i
dotprod(k,m)=v1ni*crossi+v1nj*crossj+v1nk*crossk
enddo
enddo
min_average=1000.
do m=1,num_faces(i)
average(m)=0.
do k=1,8
average(m)=average(m)+dotprod(k,m)
enddo
average(m)=average(m)/8.
if(average(m)<min_average)min_average=average(m)
enddo
distance(i,j)=min_average
enddo
enddo
!
! Copy new data into updated input file
rewind(unit=10)
open(unit=12,file='GeomGenINP.inp',status='unknown')
input2(1)='**'
do while (index(input2(1),'*End Assembly')==0)
read(10,'(a)')input2(2)
write(12,'(a)')input2(1)
input2(1)=input2(2)
enddo
write(12,'(a)')'*End Assembly'
write(12,*)'*INITIAL CONDITIONS,TYPE=SOLUTION'
open(unit=13,file='ecor.dat',status='old')
active=0
ierr=0
do while (ierr==0)
read(13,*,iostat=ierr)ielnum
if(ierr==0)active(ielnum)=1
enddo
do i=1,num_cells
do j=1,num_elements(i)
write(12,'(a,8(i6,a))')'Assembly.CorPart.',elem_label(i,j),',',elem_neighbours(i,j,1),&
& ',',elem_neighbours(i,j,2),',',elem_neighbours(i,j,3),',',elem_neighbours(i,j,4),&
& ',',elem_neighbours(i,j,5),',',elem_neighbours(i,j,6),',',0,','
write(12,'(2(i6,a),f18.6,a,5(i6,a))')elem_label(i,j),',',active(elem_label(i,j)),',',&
& distance(i,j),',',0,',',0,',',0,',',0,',',0,','
write(12,'(8(i6,a))')0,',',0,',',0,',',0,',',1,',',0,',',0,',',0,','
write(12,'(6(i6,a),f18.6)')0,',',0,',',0,',',0,',',0,',',0,',',0.
enddo
enddo
ierr=0
do while (ierr==0)
read(10,'(a)',iostat=ierr)input2(1)
if(ierr==0)write(12,'(a)')input2(1)
enddo
close(unit=10)
close(unit=11)
close(unit=12)
close(unit=13)
End Program

View file

@ -0,0 +1,190 @@
!This program calculates the distance from each element
!to its nearest grain boundary
Program GeomGenPost
!
! Parameters
parameter(max_nodes=1000000,max_elements=1000000,max_node_in_elem=8)
parameter(max_cells=1000,max_elem_in_cell=10000,max_neigh_per_elem=6)
parameter(max_faces_in_cell=100)
!
! Declare Variables
character*256 input,input2(2)
integer elements(max_elements,max_node_in_elem)
integer active(max_elements)
integer num_elements(max_cells)
integer elem_label(max_cells,max_elem_in_cell)
integer num_neighbours(max_cells,max_elem_in_cell)
integer elem_neighbours(max_cells,max_elem_in_cell,max_neigh_per_elem)
integer num_faces(max_cells)
integer fstatus(max_cells,max_faces_in_cell)
real nodes(max_nodes,3)
real fnorm(max_cells,max_faces_in_cell,3)
real fpoint(max_cells,max_faces_in_cell,3)
real dotprod(max_node_in_elem,max_faces_in_cell)
real average(max_faces_in_cell)
real distance(max_cells,max_elem_in_cell)
!
! Initialise Variables
nodes=0.
fnorm=0.
fpoint=0.
dotprod=0.
average=0.
distance=0.
elements=0
active=0
num_elements=0
elem_label=0
num_neighbours=0
elem_neighbours=0
num_faces=0
fstatus=0
!
! Open Input File and read node and element co-ordinates
open(unit=10,file='GeomGenTemp.inp',status='unknown')
do while (index(input,'*Node')==0)
read(10,'(a)')input
end do
nn=0
do while(1==1)
read(10,'(a)')input
if(index(input,'*')==0)then
backspace(10)
nn=nn+1
read(10,*)dummy,nodes(nn,1),nodes(nn,2),nodes(nn,3)
else
if(index(input,'C3D8')/=0)nele_type=8
if(index(input,'C3D4')/=0)nele_type=4
exit
endif
end do
ne=0
do while(1==1)
read(10,'(a)')input
if(index(input,'*')==0)then
backspace(10)
ne=ne+1
if(nele_type==8)then
read(10,*)dummy,elements(ne,1),elements(ne,2),elements(ne,3),elements(ne,4)&
& ,elements(ne,5),elements(ne,6),elements(ne,7),elements(ne,8)
elseif(nele_type==4)then
read(10,*)dummy,elements(ne,1),elements(ne,2),elements(ne,3),elements(ne,4)
endif
else
exit
endif
end do
!
! Open GeomGen output file and read element connectivity, cell, face and
! vertice data.
open(unit=11,file='vertout.dat',status='old')
read(11,*)idimension
read(11,*)num_cells
do i=1,num_cells
read(11,*)num_elements(i)
do j=1,num_elements(i)
read(11,*)elem_label(i,j)
read(11,*)num_neighbours(i,j)
do k=1,num_neighbours(i,j)
read(11,*)elem_neighbours(i,j,k)
enddo
enddo
read(11,*)num_faces(i)
do j=1,num_faces(i)
read(11,*)vert1x,vert1y,vert1z
read(11,*)vert2x,vert2y,vert2z
read(11,*)vert3x,vert3y,vert3z
v1v2i=vert1x-vert2x
v1v2j=vert1y-vert2y
v1v2k=vert1z-vert2z
v1v3i=vert1x-vert3x
v1v3j=vert1y-vert3y
v1v3k=vert1z-vert3z
crossi=v1v2j*v1v3k-v1v2k*v1v3j
crossj=v1v2k*v1v3i-v1v2i*v1v3k
crossk=v1v2i*v1v3j-v1v2j*v1v3i
cmag=sqrt(crossi*crossi+crossj*crossj+crossk*crossk)
fnorm(i,j,1)=crossi/cmag
fnorm(i,j,2)=crossj/cmag
fnorm(i,j,3)=crossk/cmag
fpoint(i,j,1)=vert1x
fpoint(i,j,2)=vert1y
fpoint(i,j,3)=vert1z
if(idimension==2)then
if(int(fnorm(i,j,1))==0.and.int(fnorm(i,j,2))==0.and.int(abs(fnorm(i,j,3)))==1)then
fstatus(i,j)=1
endif
endif
enddo
enddo
!
! Determine normal distance between element centroid and closest face
do i=1,num_cells
do j=1,num_elements(i)
do k=1,nele_type
rnodex=nodes(elements(elem_label(i,j),k),1)
rnodey=nodes(elements(elem_label(i,j),k),2)
rnodez=nodes(elements(elem_label(i,j),k),3)
do m=1,num_faces(i)
if(fstatus(i,m)/=1)then
v1ni=fpoint(i,m,1)-rnodex
v1nj=fpoint(i,m,2)-rnodey
v1nk=fpoint(i,m,3)-rnodez
dotprod(k,m)=v1ni*fnorm(i,m,1)+v1nj*fnorm(i,m,2)+v1nk*fnorm(i,m,3)
endif
enddo
enddo
rmin_average=1000.
do m=1,num_faces(i)
if(fstatus(i,m)/=1)then
average(m)=0.
do k=1,nele_type
average(m)=average(m)+abs(dotprod(k,m))
enddo
average(m)=average(m)/float(nele_type)
if(average(m)<rmin_average)rmin_average=average(m)
endif
enddo
distance(i,j)=rmin_average
enddo
enddo
!
! Copy new data into updated input file
rewind(unit=10)
open(unit=12,file='GeomGenINP.inp',status='unknown')
input2(1)='**'
do while (index(input2(1),'*End Assembly')==0)
read(10,'(a)')input2(2)
write(12,'(a)')input2(1)
input2(1)=input2(2)
enddo
write(12,'(a)')'*End Assembly'
write(12,*)'*INITIAL CONDITIONS,TYPE=SOLUTION'
open(unit=13,file='ecor.dat',status='old')
active=0
ierr=0
do while (ierr==0)
read(13,*,iostat=ierr)ielnum
if(ierr==0)active(ielnum)=1
enddo
do i=1,num_cells
do j=1,num_elements(i)
write(12,'(a,8(i6,a))')'Assembly.CorPart.',elem_label(i,j),',',elem_neighbours(i,j,1),&
& ',',elem_neighbours(i,j,2),',',elem_neighbours(i,j,3),',',elem_neighbours(i,j,4),&
& ',',elem_neighbours(i,j,5),',',elem_neighbours(i,j,6),',',0,','
write(12,'(2(i6,a),f18.6,a,5(i6,a))')elem_label(i,j),',',active(elem_label(i,j)),',',&
& distance(i,j),',',0,',',0,',',0,',',0,',',0,','
write(12,'(8(i6,a))')0,',',0,',',0,',',0,',',1,',',0,',',0,',',0,','
write(12,'(6(i6,a),f18.6)')0,',',0,',',0,',',0,',',0,',',0,',',0.
enddo
enddo
ierr=0
do while (ierr==0)
read(10,'(a)',iostat=ierr)input2(1)
if(ierr==0)write(12,'(a)')input2(1)
enddo
close(unit=10)
close(unit=11)
close(unit=12)
close(unit=13)
End Program

View file

@ -0,0 +1,74 @@
!This program calculates the distance from each element
!to its nearest grain boundary
Program GeomGenPost
!
! Parameters
parameter(max_elements=1000000)
parameter(max_neigh_per_elem=6)
!
! Declare Variables
character*256 input,input2(2)
integer active(max_elements)
integer cellstat(max_elements)
integer elem_neighbours(max_neigh_per_elem)
!
! Initialise Variables
active=0
elem_neighbours=0
!
! Copy new data into updated input file
open(unit=10,file='GeomGenTemp.inp',status='unknown')
open(unit=12,file='GeomGenINP.inp',status='unknown')
input2(1)='**'
do while (index(input2(1),'*End Assembly')==0)
read(10,'(a)')input2(2)
write(12,'(a)')input2(1)
input2(1)=input2(2)
enddo
write(12,'(a)')'*End Assembly'
write(12,*)'*INITIAL CONDITIONS,TYPE=SOLUTION'
open(unit=13,file='ecor.dat',status='old')
active=0
ierr=0
do while (ierr==0)
read(13,*,iostat=ierr)ielnum
if(ierr==0)active(ielnum)=1
enddo
open(unit=14,file='testout.dat',status='old')
ierr=0
do while (ierr==0)
read(13,*,iostat=ierr)ielnum,icell
if(ierr==0)cellstat(ielnum)=icell
enddo
! Open GeomGen output file and read element connectivity, cell, face and
! vertice data.
open(unit=11,file='vertout.dat',status='old')
read(11,*)num_cells
do i=1,num_cells
read(11,*)num_elements
do j=1,num_elements
read(11,*)ielem_label
read(11,*)num_neighbours
do k=1,num_neighbours
read(11,*)elem_neighbours(k)
enddo
read(11,*)distance
write(12,'(a,8(i6,a))')'Assembly.CorPart.',ielem_label,',',elem_neighbours(1),&
& ',',elem_neighbours(2),',',elem_neighbours(3),',',elem_neighbours(4),&
& ',',elem_neighbours(5),',',elem_neighbours(6),',',0,','
write(12,'(2(i6,a),f18.6,a,5(i6,a))')ielem_label,',',active(elem_label),',',&
& distance,',',cellstat(ielem_label),',',0,',',0,',',0,',',0,','
write(12,'(8(i6,a))')0,',',0,',',0,',',0,',',1,',',0,',',0,',',0,','
write(12,'(6(i6,a),f18.6)')0,',',0,',',0,',',0,',',0,',',0,',',0.
enddo
enddo
ierr=0
do while (ierr==0)
read(10,'(a)',iostat=ierr)input2(1)
if(ierr==0)write(12,'(a)')input2(1)
enddo
close(unit=10)
close(unit=11)
close(unit=12)
close(unit=13)
End Program

View file

@ -0,0 +1,847 @@
# Draw a Square Grain
#
def DrawSquare(VerModel,part_type,rad,extrude_depth):
from abaqusConstants import *
from abaqus import *
label='Base'
if part_type==3:
VerPart=VerModel.Part(name=label, dimensionality=THREE_D,type=DEFORMABLE_BODY)
else:
VerPart=VerModel.Part(name=label, dimensionality=TWO_D_PLANAR,type=DEFORMABLE_BODY)
VerPart.DatumPointByCoordinate((0,0,0))
VerPart.DatumPointByCoordinate((1,0,0))
VerPart.DatumPointByCoordinate((0,1,0))
pdatums=VerPart.datums
VerPart.DatumPlaneByThreePoints(point1=pdatums[1], point2=pdatums[2], point3=pdatums[3])
VerPart.DatumAxisByTwoPoint(point1=pdatums[1],point2=pdatums[2])
partTransform = VerPart.MakeSketchTransform(sketchPlane=pdatums[4], sketchUpEdge=pdatums[5],
sketchPlaneSide=SIDE1, sketchOrientation=BOTTOM, origin=(0,0,0))
VerSketch = VerModel.ConstrainedSketch(name=label,sheetSize=200, transform=partTransform)
VerSketch.Line(point1=(0.,0.),point2=(rad,0.))
VerSketch.Line(point1=(rad,0.),point2=(rad,rad))
VerSketch.Line(point1=(rad,rad),point2=(0.,rad))
VerSketch.Line(point1=(0.,rad),point2=(0.,0.))
if part_type==3:
VerPart.BaseSolidExtrude(sketch=VerSketch,depth=extrude_depth)
else:
VerPart.BaseShell(sketch=VerSketch)
# Draw a Hexagonal Grain
#
def DrawHexagon(VerModel,part_type,rad,extrude_depth):
from abaqusConstants import *
from abaqus import *
label='Base'
VerAssembly=VerModel.rootAssembly
if part_type==3:
VerPart=VerModel.Part(name=label, dimensionality=THREE_D,type=DEFORMABLE_BODY)
else:
VerPart=VerModel.Part(name=label, dimensionality=TWO_D_PLANAR,type=DEFORMABLE_BODY)
VerPart.DatumPointByCoordinate((0,0,0))
VerPart.DatumPointByCoordinate((1,0,0))
VerPart.DatumPointByCoordinate((0,1,0))
pdatums=VerPart.datums
VerPart.DatumPlaneByThreePoints(point1=pdatums[1], point2=pdatums[2], point3=pdatums[3])
VerPart.DatumAxisByTwoPoint(point1=pdatums[1],point2=pdatums[2])
partTransform = VerPart.MakeSketchTransform(sketchPlane=pdatums[4], sketchUpEdge=pdatums[5],
sketchPlaneSide=SIDE1, sketchOrientation=BOTTOM, origin=(0,0,0))
VerSketch = VerModel.ConstrainedSketch(name=label,sheetSize=200, transform=partTransform)
yheight=sin(radians(30.))
xheight=cos(radians(30.))
VerSketch.Line(point1=(0.,0.),point2=(rad*xheight,rad*yheight))
VerSketch.Line(point1=(rad*xheight,rad*yheight),point2=(rad*xheight,rad*yheight+rad))
VerSketch.Line(point1=(rad*xheight,rad*yheight+rad),point2=(0.,2.*rad*yheight+rad))
VerSketch.Line(point1=(0.,2.*rad*yheight+rad),point2=(-rad*xheight,rad*yheight+rad))
VerSketch.Line(point1=(-rad*xheight,rad*yheight+rad),point2=(-rad*xheight,rad*yheight))
VerSketch.Line(point1=(-rad*xheight,rad*yheight),point2=(0.,0.))
if part_type==3:
VerPart.BaseSolidExtrude(sketch=VerSketch,depth=extrude_depth)
else:
VerPart.BaseShell(sketch=VerSketch)
BasePart=VerModel.parts['Base']
BasePartCells = BasePart.cells
BasePartFaces = BasePart.faces
BasePartVerts = BasePart.vertices
if part_type==3:
BasePart.PartitionCellByPlaneThreePoints(point1=BasePartVerts[4], point2=BasePartVerts[10],
point3=BasePartVerts[11], cells=BasePartCells)
else:
BasePart.PartitionFaceByShortestPath(point1=BasePartVerts[4], point2=BasePartVerts[1],
faces=BasePartFaces)
# Draw a Dodecahedral Grain
#
def DrawDodec(VerModel,rad):
from abaqusConstants import *
from abaqus import *
label='BaseTemp'
VerAssembly=VerModel.rootAssembly
VerPart=VerModel.Part(name=label, dimensionality=THREE_D,type=DEFORMABLE_BODY)
VerPart.DatumPointByCoordinate((0,0,0))
VerPart.DatumPointByCoordinate((1,0,0))
VerPart.DatumPointByCoordinate((0,1,0))
pdatums=VerPart.datums
VerPart.DatumPlaneByThreePoints(point1=pdatums[1], point2=pdatums[2], point3=pdatums[3])
VerPart.DatumAxisByTwoPoint(point1=pdatums[1],point2=pdatums[2])
partTransform = VerPart.MakeSketchTransform(sketchPlane=pdatums[4], sketchUpEdge=pdatums[5],
sketchPlaneSide=SIDE1, sketchOrientation=BOTTOM, origin=(0,0,0))
VerSketch = VerModel.ConstrainedSketch(name=label,sheetSize=200, transform=partTransform)
VerSketch.Line(point1=(0.,0.),point2=(sqrt(2.)*rad,rad))
VerSketch.Line(point1=(sqrt(2.)*rad,rad),point2=(0.,2.*rad))
VerSketch.Line(point1=(0.,2.*rad),point2=(-sqrt(2.)*rad,rad))
VerSketch.Line(point1=(-sqrt(2.)*rad,rad),point2=(0.,0.))
VerPart.BaseShell(sketch=VerSketch)
for i in range (1,13):
dodecname='dodec'+str(i)
VerAssembly.Instance(name=dodecname,part=VerPart, dependent=ON)
VerAssembly.translate(instanceList=('dodec2', ), vector=(0.,0.,-2.*sqrt(2.)*rad))
VerAssembly.rotate(instanceList=('dodec3','dodec4', ), axisPoint=(0.0, 0.0, 0.0),
axisDirection=(0.0, 1., 0.0), angle=90.0)
VerAssembly.translate(instanceList=('dodec3', ), vector=(sqrt(2.)*rad,0.,0.))
VerAssembly.translate(instanceList=('dodec4', ), vector=(-sqrt(2.)*rad,0.,0.))
VerAssembly.translate(instanceList=('dodec3','dodec4', ), vector=(0.,0.,-sqrt(2.)*rad))
VerAssembly.rotate(instanceList=('dodec5','dodec6','dodec7','dodec8',),
axisPoint=(-sqrt(2.)*rad, rad, 0.0), axisDirection=(0., 0., 1.), angle=90.0)
VerAssembly.rotate(instanceList=('dodec5','dodec6','dodec7','dodec8',),
axisPoint=(-sqrt(2.)*rad, rad, 0.0), axisDirection=(0., 1., 0.), angle=-45.0)
VerAssembly.rotate(instanceList=('dodec5','dodec6','dodec7','dodec8',),
axisPoint=(-sqrt(2.)*rad, rad, 0.0), axisDirection=(1., 0., 1.), angle=-45.0)
VerAssembly.rotate(instanceList=('dodec6',),
axisPoint=(0., rad, -sqrt(2.)*rad), axisDirection=(0., 1., 0.), angle=90.0)
VerAssembly.rotate(instanceList=('dodec7',),
axisPoint=(0., rad, -sqrt(2.)*rad), axisDirection=(0., 1., 0.), angle=180.0)
VerAssembly.rotate(instanceList=('dodec8',),
axisPoint=(0., rad, -sqrt(2.)*rad), axisDirection=(0., 1., 0.), angle=270.0)
VerAssembly.rotate(instanceList=('dodec9','dodec10','dodec11','dodec12',),
axisPoint=(-sqrt(2.)*rad, rad, 0.0), axisDirection=(0., 0., 1.), angle=-90.0)
VerAssembly.rotate(instanceList=('dodec9','dodec10','dodec11','dodec12',),
axisPoint=(-sqrt(2.)*rad, rad, 0.0), axisDirection=(0., 1., 0.), angle=-45.0)
VerAssembly.rotate(instanceList=('dodec9','dodec10','dodec11','dodec12',),
axisPoint=(-sqrt(2.)*rad, rad, 0.0), axisDirection=(1., 0., 1.), angle=45.0)
VerAssembly.rotate(instanceList=('dodec10',),
axisPoint=(0., rad, -sqrt(2.)*rad), axisDirection=(0., -1., 0.), angle=90.0)
VerAssembly.rotate(instanceList=('dodec11',),
axisPoint=(0., rad, -sqrt(2.)*rad), axisDirection=(0., -1., 0.), angle=180.0)
VerAssembly.rotate(instanceList=('dodec12',),
axisPoint=(0., rad, -sqrt(2.)*rad), axisDirection=(0., -1., 0.), angle=270.0)
VerAssembly.InstanceFromBooleanMerge(name='Base', instances=(
VerAssembly.instances['dodec1'],
VerAssembly.instances['dodec2'], VerAssembly.instances['dodec3'],
VerAssembly.instances['dodec4'], VerAssembly.instances['dodec5'],
VerAssembly.instances['dodec6'], VerAssembly.instances['dodec7'],
VerAssembly.instances['dodec8'], VerAssembly.instances['dodec9'],
VerAssembly.instances['dodec10'],VerAssembly.instances['dodec11'],
VerAssembly.instances['dodec12'], ),
keepIntersections=ON, originalInstances=SUPPRESS, domain=GEOMETRY)
VerPart=VerModel.parts['Base']
VerPart.AddCells(faceList = VerPart.faces)
for i in range (1,12):
dodecname='dodec'+str(i)
del VerAssembly.instances[dodecname]
del VerAssembly.instances['Base-1']
# Draw a 2D Voronoi Tessellation
#
def Voronoi2D(VerModel,part_type,extrude_depth,num_grains,maxsize,hard_rad,random_seed):
from abaqusConstants import *
from abaqus import *
import random
import subprocess
xlist=[0.]
ylist=[0.]
VerAssembly=VerModel.rootAssembly
random.seed(random_seed)
qhullin=open('qhullin.dat','w')
qhullin.write("%i \n"%(2))
qhullin.write("%i \n"%(num_grains*9))
for i in range(0,num_grains):
outside=False
while outside==False:
xcor=random.random()*maxsize
ycor=random.random()*maxsize
if hard_rad==0.:
outside=True
break
if len(xlist)>1:
distold=1000.
for i in range(1,len(xlist)):
distnew=(xcor-xlist[i])*(xcor-xlist[i])+(ycor-ylist[i])*(ycor-ylist[i])
distnew=sqrt(distnew)
if distnew<distold:
distold=distnew
if distold>=hard_rad:
outside=True
else:
outside=True
xlist.append(xcor)
ylist.append(ycor)
qhullin.write("%18.6f %18.6f \n"%(xcor,ycor))
qhullin.write("%18.6f %18.6f \n"%(xcor+maxsize,ycor))
qhullin.write("%18.6f %18.6f \n"%(xcor-maxsize,ycor))
qhullin.write("%18.6f %18.6f \n"%(xcor,ycor+maxsize))
qhullin.write("%18.6f %18.6f \n"%(xcor,ycor-maxsize))
qhullin.write("%18.6f %18.6f \n"%(xcor+maxsize,ycor+maxsize))
qhullin.write("%18.6f %18.6f \n"%(xcor-maxsize,ycor-maxsize))
qhullin.write("%18.6f %18.6f \n"%(xcor+maxsize,ycor-maxsize))
qhullin.write("%18.6f %18.6f \n"%(xcor-maxsize,ycor+maxsize))
qhullin.close()
scales=open('scales.dat','w')
scales.write("%18.6f \n"%(maxsize))
scales.close()
# retcode=subprocess.call("qhull.exe v Qbb TI qhullin.dat o TO qhullout.dat")
retcode=subprocess.call("Voronoi2DPost.exe")
FortranFile=open('fortranout.dat')
num_cells=int(FortranFile.readline())
cordx=[]
cordy=[]
x1=[]
y1=[]
x2=[]
y2=[]
k=0
for i in range(0,num_cells):
label='Cell'+str(i)
if part_type==3:
VerPart=VerModel.Part(name=label, dimensionality=THREE_D,type=DEFORMABLE_BODY)
else:
VerPart=VerModel.Part(name=label, dimensionality=TWO_D_PLANAR,type=DEFORMABLE_BODY)
# Constuct Datum Point At Each Node
VerPart.DatumPointByCoordinate((0,0,0))
VerPart.DatumPointByCoordinate((1,0,0))
VerPart.DatumPointByCoordinate((0,1,0))
pdatums=VerPart.datums
# Constuct Datum Plane on Element Face and Datum Axis Along Element Base
VerPart.DatumPlaneByThreePoints(point1=pdatums[1],
point2=pdatums[2], point3=pdatums[3])
VerPart.DatumAxisByTwoPoint(point1=pdatums[1],point2=pdatums[2])
# Sketch New Part Geometry Over Original Element
partTransform = VerPart.MakeSketchTransform(sketchPlane=pdatums[4],
sketchUpEdge=pdatums[5],
sketchPlaneSide=SIDE1, sketchOrientation=BOTTOM, origin=(0,0,0))
VerSketch = VerModel.ConstrainedSketch(name=label,sheetSize=200,
transform=partTransform)
num_verts=int(FortranFile.readline())
for j in range(0,num_verts):
coords=FortranFile.readline().split(',')
cordx.append([])
cordy.append([])
cordx[j]=float(coords[0])
cordy[j]=float(coords[1])
print i,num_verts
for j in range(0,num_verts-1):
VerSketch.Line(point1=(cordx[j],cordy[j]),point2=(cordx[j+1],cordy[j+1]))
x1.append([])
y1.append([])
x1[k]=cordx[j]
y1[k]=cordy[j]
x2.append([])
y2.append([])
x2[k]=cordx[j+1]
y2[k]=cordy[j+1]
k=k+1
VerSketch.Line(point1=(cordx[num_verts-1],cordy[num_verts-1]),
point2=(cordx[0],cordy[0]))
x1.append([])
y1.append([])
x1[k]=cordx[num_verts-1]
y1[k]=cordy[num_verts-1]
x2.append([])
y2.append([])
x2[k]=cordx[0]
y2[k]=cordy[0]
k=k+1
print i,num_verts,k
if part_type==3:
VerPart.BaseSolidExtrude(sketch=VerSketch, depth=extrude_depth)
else:
VerPart.Shell(sketchPlane=pdatums[4], sketchUpEdge=pdatums[5], sketchPlaneSide=SIDE1,
sketchOrientation=BOTTOM, sketch=VerSketch)
VerAssembly.Instance(name=label,part=VerPart)
inst=[]
inst.append([])
for i in range(0,num_cells):
inst[i]=VerAssembly.instances['Cell'+str(i)]
if i<num_cells-1:
inst.append([])
VerAssembly.InstanceFromBooleanMerge(name='Merged',
instances=inst,originalInstances=DELETE, keepIntersections=ON,domain=GEOMETRY)
# Draw a 3D Voronoi Tessellation
#
def Voronoi3D(VerModel,num_grains,maxsize,hard_rad,random_seed):
from abaqusConstants import *
from abaqus import *
import random
import subprocess
xlist=[0.]
ylist=[0.]
zlist=[0.]
VerAssembly=VerModel.rootAssembly
random.seed(random_seed)
qhullin=open('qhullin.dat','w')
qhullin.write("%i \n"%(3))
qhullin.write("%i \n"%(num_grains*27))
for i in range(0,num_grains):
outside=False
while outside==False:
xcor=random.random()*maxsize
ycor=random.random()*maxsize
zcor=random.random()*maxsize
if hard_rad==0.:
outside=True
break
if len(xlist)>1:
distold=1000.
for i in range(1,len(xlist)):
distnew=(xcor-xlist[i])*(xcor-xlist[i])+(ycor-ylist[i])*(ycor-ylist[i])
distnew=distnew+(zcor-zlist[i])*(zcor-zlist[i])
distnew=sqrt(distnew)
if distnew<distold:
distold=distnew
if distold>=hard_rad:
outside=True
else:
outside=True
xlist.append(xcor)
ylist.append(ycor)
zlist.append(zcor)
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor,ycor,zcor))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor+maxsize,ycor,zcor))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor-maxsize,ycor,zcor))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor,ycor+maxsize,zcor))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor,ycor-maxsize,zcor))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor+maxsize,ycor+maxsize,zcor))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor-maxsize,ycor-maxsize,zcor))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor+maxsize,ycor-maxsize,zcor))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor-maxsize,ycor+maxsize,zcor))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor,ycor,zcor+maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor+maxsize,ycor,zcor+maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor-maxsize,ycor,zcor+maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor,ycor+maxsize,zcor+maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor,ycor-maxsize,zcor+maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor+maxsize,ycor+maxsize,zcor+maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor-maxsize,ycor-maxsize,zcor+maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor+maxsize,ycor-maxsize,zcor+maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor-maxsize,ycor+maxsize,zcor+maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor,ycor,zcor-maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor+maxsize,ycor,zcor-maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor-maxsize,ycor,zcor-maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor,ycor+maxsize,zcor-maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor,ycor-maxsize,zcor-maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor+maxsize,ycor+maxsize,zcor-maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor-maxsize,ycor-maxsize,zcor-maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor+maxsize,ycor-maxsize,zcor-maxsize))
qhullin.write("%18.6f %18.6f %18.6f \n"%(xcor-maxsize,ycor+maxsize,zcor-maxsize))
qhullin.close()
scales=open('scales.dat','w')
scales.write("%18.6f \n"%(maxsize))
scales.close()
# retcode=subprocess.call("qvoronoi.exe TI qhullin.dat o Fi TO qhullout.dat")
retcode=subprocess.call("Voronoi3DPost.exe")
FortranFile=open('fortranout.dat')
num_cells=int(FortranFile.readline())
cordx=[]
cordy=[]
cordz=[]
x1=[]
y1=[]
x2=[]
y2=[]
k=0
for k in range(0,num_cells):
num_hyp=int(FortranFile.readline())
for i in range(0,num_hyp):
label='C'+str(k)+'H'+str(i)
VerPart=VerModel.Part(name=label, dimensionality=THREE_D,type=DEFORMABLE_BODY)
# Constuct Datum Point At Each Node
num_verts=int(FortranFile.readline())
for j in range(0,num_verts):
coords=FortranFile.readline().split(',')
cordx.append([])
cordy.append([])
cordz.append([])
cordx[j]=float(coords[0])
cordy[j]=float(coords[1])
cordz[j]=float(coords[2])
VerPart.DatumPointByCoordinate((cordx[j],cordy[j],cordz[j]))
pdatums=VerPart.datums
p1x=pdatums[1].pointOn[0]
p1y=pdatums[1].pointOn[1]
p1z=pdatums[1].pointOn[2]
tol=1.e-4
for m in range(2,num_verts+1):
px=pdatums[m].pointOn[0]
py=pdatums[m].pointOn[1]
pz=pdatums[m].pointOn[2]
p1pk=sqrt((p1x-px)*(p1x-px)+(p1y-py)*(p1y-py)+(p1z-pz)*(p1z-pz))
if p1pk>tol:
index1=m
p2x=px
p2y=py
p2z=pz
break
for m in range(2,num_verts+1):
if m!=index1:
px=pdatums[m].pointOn[0]
py=pdatums[m].pointOn[1]
pz=pdatums[m].pointOn[2]
p1pk=sqrt((p1x-px)*(p1x-px)+(p1y-py)*(p1y-py)+(p1z-pz)*(p1z-pz))
p2pk=sqrt((p2x-px)*(p2x-px)+(p2y-py)*(p2y-py)+(p2z-pz)*(p2z-pz))
if p1pk>tol:
if p2pk>tol:
index2=m
break
VerPart.DatumPlaneByThreePoints(point1=pdatums[1], point2=pdatums[index1], point3=pdatums[index2])
VerPart.DatumAxisByTwoPoint(point1=pdatums[1],point2=pdatums[index1])
partTransform = VerPart.MakeSketchTransform(sketchPlane=pdatums[num_verts+1],
sketchUpEdge=pdatums[num_verts+2], sketchPlaneSide=SIDE1, sketchOrientation=BOTTOM, origin=(0.,0.,0.))
sklabel='Skbase'+'C'+str(k)+'H'+str(i)
VerSketch=VerModel.ConstrainedSketch(name=sklabel,sheetSize=200, transform=partTransform)
VerPart.projectReferencesOntoSketch(sketch=VerSketch, filter=COPLANAR_EDGES)
verts=VerSketch.vertices
centroidx=0.
centroidy=0.
angle=[]
jnum=[]
for j in range(0,num_verts):
centroidx=centroidx+verts[j].coords[0]
centroidy=centroidy+verts[j].coords[1]
centroidx=centroidx/float(num_verts)
centroidy=centroidy/float(num_verts)
for j in range(0,num_verts):
pointx=verts[j].coords[0]-centroidx
pointy=verts[j].coords[1]-centroidy
vertangle=atan2(pointy,pointx)
if vertangle<0.:
vertangle=2*pi+vertangle
angle.append(vertangle)
jnum.append(j)
icheck=0
while icheck==0:
icheck=1
for j in range(1,num_verts):
if angle[j]<angle[j-1]:
temp1=angle[j-1]
temp2=jnum[j-1]
angle[j-1]=angle[j]
angle[j]=temp1
jnum[j-1]=jnum[j]
jnum[j]=temp2
icheck=0
for j in range(1,num_verts):
x1=verts[jnum[j]].coords[0]
x2=verts[jnum[j-1]].coords[0]
y1=verts[jnum[j]].coords[1]
y2=verts[jnum[j-1]].coords[1]
VerSketch.Line(point1=(x1,y1),point2=(x2,y2))
VerSketch.Line(point1=(verts[jnum[num_verts-1]].coords[0],
verts[jnum[num_verts-1]].coords[1]),
point2=(verts[jnum[0]].coords[0],verts[jnum[0]].coords[1]))
VerPart.Shell(sketchPlane=pdatums[num_verts+1], sketchPlaneSide=SIDE1,
sketchUpEdge=pdatums[num_verts+2],sketchOrientation=BOTTOM,sketch=VerSketch)
label='Part'+'C'+str(k)+'H'+str(i)
VerAssembly.Instance(name=label,part=VerPart)
inst=[]
inst.append([])
for i in range(0,num_hyp):
inst[i]=VerAssembly.instances['Part'+'C'+str(k)+'H'+str(i)]
if i<num_hyp-1:
inst.append([])
VerAssembly.InstanceFromBooleanMerge(name='Merged'+str(k),
instances=inst,originalInstances=DELETE, keepIntersections=ON,domain=GEOMETRY)
shellpart=VerModel.parts['Merged'+str(k)]
shellpart.AddCells(faceList = shellpart.faces)
VerAssembly.Instance(name='Part'+str(k),part=shellpart, dependent=ON)
del VerAssembly.instances['Merged'+str(k)+'-1']
for i in range(0,num_hyp):
del VerModel.sketches['Skbase'+'C'+str(k)+'H'+str(i)]
del VerModel.parts['C'+str(k)+'H'+str(i)]
print float(k)/float(num_cells)
inst=[]
inst.append([])
for i in range(0,num_cells):
inst[i]=VerAssembly.instances['Part'+str(i)]
if i<num_cells-1:
inst.append([])
VerAssembly.InstanceFromBooleanMerge(name='Merged',
instances=inst,originalInstances=DELETE, keepIntersections=ON,domain=GEOMETRY)
# Make a Boolean Template Part
#
def BooleanPart(VerModel,part_type,rad,extrude_depth,
num_high,num_wide,num_thick,shape,dimension,scalex,scaley,scalez):
from abaqusConstants import *
from abaqus import *
VerAssembly=VerModel.rootAssembly
booSketch=VerModel.ConstrainedSketch(name='BSmall', sheetSize=20.0)
if shape==1:
vert1x=0.
vert1y=0.
vert2x=rad*num_high
vert2y=0.
vert3x=rad*num_high
vert3y=rad*num_wide
vert4x=0.
vert4y=rad*num_wide
edepth=extrude_depth*num_thick
if shape==2:
yheight=sin(radians(30.))
xheight=cos(radians(30.))
vert1x=0.
vert1y=rad*yheight+rad/2.
vert2x=rad*xheight*(float(num_high)-1.)*2.
vert2y=rad*yheight+rad/2.
vert3x=rad*xheight*(float(num_high)-1.)*2.
vert3y=rad*yheight+rad/2.+(float(num_wide)-1.)*(rad+rad*yheight)
vert4x=0.
vert4y=rad*yheight+rad/2.+(float(num_wide)-1.)*(rad+rad*yheight)
edepth=extrude_depth*num_thick
if shape==3:
vert1x=0.
vert1y=rad
vert2x=sqrt(2.)*rad*(2.*float(num_high)-1.)
vert2y=rad
vert3x=sqrt(2.)*rad*(2.*float(num_high)-1.)
vert3y=rad*(2.*float(num_wide)-1.)
vert4x=0.
vert4y=rad*(2.*float(num_wide)-1.)
edepth=sqrt(2.)*rad*(2.*float(num_thick)-1.)
if shape==4:
vert1x=0.
vert1y=0.
vert2x=scalex
vert2y=0.
vert3x=scalex
vert3y=scaley
vert4x=0.
vert4y=scaley
if dimension==2:
edepth=extrude_depth
else:
edepth=scalez
booSketch.Line(point1=(vert1x,vert1y), point2=(vert2x, vert2y))
booSketch.Line(point1=(vert2x, vert2y), point2=(vert3x, vert3y))
booSketch.Line(point1=(vert3x, vert3y), point2=(vert4x, vert4y))
booSketch.Line(point1=(vert4x, vert4y), point2=(vert1x, vert1y))
if part_type==3:
booPart=VerModel.Part(name='BSmall', dimensionality=THREE_D,type=DEFORMABLE_BODY)
booPart.BaseSolidExtrude(sketch=booSketch, depth=edepth)
else:
booPart=VerModel.Part(name='BSmall', dimensionality=TWO_D_PLANAR,type=DEFORMABLE_BODY)
booPart.BaseShell(sketch=booSketch)
booSketchB=VerModel.ConstrainedSketch(name='BBig', sheetSize=20.0)
booSketchB.Line(point1=(vert1x-10.,vert1y-10.), point2=(vert2x+10., vert2y-10.))
booSketchB.Line(point1=(vert2x+10., vert2y-10.), point2=(vert3x+10., vert3y+10.))
booSketchB.Line(point1=(vert3x+10., vert3y+10.), point2=(vert4x-10., vert4y+10.))
booSketchB.Line(point1=(vert4x-10., vert4y+10.), point2=(vert1x-10., vert1y-10.))
if part_type==3:
booPartb=VerModel.Part(name='BBig', dimensionality=THREE_D,type=DEFORMABLE_BODY)
booPartb.BaseSolidExtrude(sketch=booSketchB, depth=edepth*10.)
else:
booPartb=VerModel.Part(name='BBig', dimensionality=TWO_D_PLANAR,type=DEFORMABLE_BODY)
booPartb.BaseShell(sketch=booSketchB)
VerAssembly.Instance(name='BSmall',part=booPart, dependent=ON)
VerAssembly.Instance(name='BBig',part=booPartb, dependent=ON)
if shape==3:
if part_type==3:
VerAssembly.translate(instanceList=('BSmall', ),
vector=(0.,0.,-sqrt(2.)*rad))
VerAssembly.translate(instanceList=('BBig', ),
vector=(0.,0.,-sqrt(2.)*rad*5.))
if shape==4:
if part_type==3:
VerAssembly.translate(instanceList=('BBig', ),
vector=(0.,0.,-edepth*5.))
VerAssembly.InstanceFromBooleanCut(name='Template',
instanceToBeCut=VerAssembly.instances['BBig'],
cuttingInstances=(VerAssembly.instances['BSmall'], ),
originalInstances=DELETE)
# Pattern base parts for multilpe grains
#
def PatternParts(num_high,num_wide,num_thick,VerPart,rad,shape,VerModel):
from abaqusConstants import *
from abaqus import *
VerAssembly=VerModel.rootAssembly
yheight=sin(radians(30.))
xheight=cos(radians(30.))
icount=0
for i in range(0,num_high):
for j in range(0,num_wide):
for k in range(0,num_thick):
label='Part'+str(icount)
VerAssembly.Instance(name=label,part=VerPart, dependent=ON)
# Square
if shape==1:
VerAssembly.translate(instanceList=(label, ),
vector=(i*rad,j*rad,k*rad))
# Hexagon
if shape==2:
if j%2==0:
VerAssembly.translate(instanceList=(label, ),
vector=(i*xheight*rad*2.,j*rad*(1.+yheight),k*rad))
else:
VerAssembly.translate(instanceList=(label, ),
vector=(i*xheight*rad*2.+xheight*rad,j*rad*(1.+yheight),k*rad))
# Dodecahedron
if shape==3:
if j%2==0:
VerAssembly.translate(instanceList=(label, ),
vector=(i*rad*2.*sqrt(2.),j*2.*rad,2.*k*rad*sqrt(2.)))
else:
VerAssembly.translate(instanceList=(label, ),
vector=(i*rad*2.*sqrt(2.)+sqrt(2.)*rad,j*2.*rad,2.*k*rad*sqrt(2.)+sqrt(2.)*rad))
icount=icount+1
inst=[]
inst.append([])
for i in range(0,icount):
inst[i]=VerAssembly.instances['Part'+str(i)]
if i<icount-1:
inst.append([])
VerAssembly.InstanceFromBooleanMerge(name='Merged',
instances=inst,originalInstances=DELETE, keepIntersections=ON,domain=GEOMETRY)
# Output vertices and element connectivity for corrosion analysis
#
def VertsConn(VerPart,dimension):
from abaqusConstants import *
from abaqus import *
vertout=open('vertout.dat','w')
vertout.write("%i\n"%(len(VerPart.cells)))
k=1.
for eachcell in VerPart.cells:
print k/float(len(VerPart.cells))
cellElements=eachcell.getElements()
vertout.write("%i\n"%(len(cellElements)))
cellFaces=eachcell.getFaces()
for eachElement in cellElements:
vertout.write("%i\n"%(eachElement.label))
Adj_Elem=eachElement.getAdjacentElements()
vertout.write("%i\n"%(len(Adj_Elem)))
for i in range(0,len(Adj_Elem)):
vertout.write("%i\n"%(Adj_Elem[i].label))
centroidx=0.
centroidy=0.
centroidz=0.
dmin=1000.
for eachNode in eachElement.getNodes():
centroidx=centroidx+eachNode.coordinates[0]
centroidy=centroidy+eachNode.coordinates[1]
centroidz=centroidz+eachNode.coordinates[2]
num_nodes=float(len(eachElement.getNodes()))
centroidx=centroidx/num_nodes
centroidy=centroidy/num_nodes
centroidz=centroidz/num_nodes
for i in range(0,len(cellFaces)):
eachFace=VerPart.faces[cellFaces[i]]
facex=eachFace.pointOn[0][0]
facey=eachFace.pointOn[0][1]
facez=eachFace.pointOn[0][2]
normalx=eachFace.getNormal()[0]
normaly=eachFace.getNormal()[1]
normalz=eachFace.getNormal()[2]
if dimension==2:
if normalx==0.:
if normaly==0.:
if abs(normalz)==1:
continue
else:
if len(Adj_Elem)<6:
if normalx==0.:
if normaly==0.:
if abs(normalz)==1:
continue
dfcx=facex-centroidx
dfcy=facey-centroidy
dfcz=facez-centroidz
distance=abs(dfcx*normalx+dfcy*normaly+dfcz*normalz)
if distance<dmin:
dmin=distance
vertout.write("%18.6f\n"%(dmin))
k=k+1
vertout.close()
# Generate Materials and Sections
#
def MatGen(ana_type,VerPart,VerModel,part_type,meshsize,random_seed):
from abaqusConstants import *
from abaqus import *
import random
if ana_type==2:
VerModel.Material(name='Magnesium')
VerModel.materials['Magnesium'].Density(table=((1e-05, ), ))
VerModel.materials['Magnesium'].Depvar(deleteVar=20, n=30)
VerModel.materials['Magnesium'].UserMaterial(
mechanicalConstants=(44000.0, 0.35, 138.7, 16.0, 165.0,0.5))
if part_type==3:
regions=VerPart.cells
else:
regions=VerPart.faces
VerModel.HomogeneousSolidSection(name='Magnesium',
material='Magnesium', thickness=meshsize)
VerPart.SectionAssignment(region=(regions,),
sectionName='Magnesium', offset=0.0, offsetField='')
else:
labelcount=1
if part_type==3:
regions=VerPart.cells
else:
regions=VerPart.faces
random.seed(random_seed)
for eachregion in regions:
rand1=(random.random()-0.5)*2.
rand2=(random.random()-0.5)*2.
rand3=(random.random()-0.5)*2.
rand4=(random.random()-0.5)*2.
rand5=(random.random()-0.5)*2.
rand6=(rand1*rand4+rand2*rand5)/(-rand3)
mlabel='Mat'+str(labelcount)
VerModel.Material(name=mlabel)
VerModel.materials[mlabel].Density(table=((1e-05, ), ))
VerModel.materials[mlabel].Depvar(deleteVar=124, n=124)
VerModel.materials[mlabel].UserMaterial(
mechanicalConstants=(200000.0, 0.3,
rand1, rand2, rand3,1.,0.,0.,rand4,rand5,rand6,0.,0.,1.,
10.,0.001,541.5,109.5,60.8,1.,1.,0.5,1.))
VerModel.HomogeneousSolidSection(name=mlabel,
material=mlabel, thickness=meshsize)
VerPart.SectionAssignment(region=(eachregion,),
sectionName=mlabel, offset=0.0, offsetField='')
labelcount=labelcount+1
# Shape 1 BCs and Constraints - Uniaxial Tension
#
def S1BCs(iNodes,VerModel,num_high,num_wide,num_thick,shape,
dimension,extrude_depth,rad,scalex,scaley,scalez):
from abaqusConstants import *
from abaqus import *
import regionToolset
VerAssembly=VerModel.rootAssembly
Min=-0.001
Max=0.001
fwide=float(num_wide)
fhigh=float(num_high)
fthick=float(num_thick)
if shape==1:
# BC LEFT
XMnBL=Min
XMxBL=Max
YMnBL=Min
YMxBL=fwide*rad+Max
ZMnBL=Min
ZMxBL=Max+extrude_depth
# BC BACK
XMnBBK=Min
XMxBBK=fhigh*rad+Max
YMnBBK=Min
YMxBBK=fwide*rad+Max
ZMnBBK=Min
ZMxBBK=Max
# BC Bottom
XMnBBT=Min
XMxBBT=fhigh*rad+Max
YMnBBT=Min
YMxBBT=Max
ZMnBBT=Min
ZMxBBT=Max+extrude_depth
# BC Right
XMnBR=fhigh*rad+Min
XMxBR=fhigh*rad+Max
YMnBR=Min
YMxBR=fwide*rad+Max
ZMnBR=Min
ZMxBR=Max+extrude_depth
# RP
XRP=fhigh*rad
YRP=fwide*rad*0.5
ZRP=extrude_depth*0.5
if shape==2:
yheight=sin(radians(30.))
xheight=cos(radians(30.))
# BC LEFT
XMnBL=Min
XMxBL=Max
YMnBL=rad*yheight+rad/2.+Min
YMxBL=rad*yheight+rad/2.+(fwide-1.)*(rad+rad*yheight)+Max
ZMnBL=Min
ZMxBL=Max+extrude_depth
# BC BACK
XMnBBK=Min
XMxBBK=rad*xheight*(fhigh-1.)*2.+Max
YMnBBK=rad*yheight+rad/2.+Min
YMxBBK=rad*yheight+rad/2.+(fwide-1.)*(rad+rad*yheight)+Max
ZMnBBK=Min
ZMxBBK=Max
# BC Bottom
XMnBBT=Min
XMxBBT=rad*xheight*(fhigh-1.)*2.+Max
YMnBBT=rad*yheight+rad/2.+Min
YMxBBT=rad*yheight+rad/2.+Max
ZMnBBT=Min
ZMxBBT=Max+extrude_depth
# BC Right
XMnBR=rad*xheight*(fhigh-1.)*2.+Min
XMxBR=rad*xheight*(fhigh-1.)*2.+Max
YMnBR=rad*yheight+rad/2.+Min
YMxBR=rad*yheight+rad/2.+(fwide-1.)*(rad+rad*yheight)+Max
ZMnBR=Min
ZMxBR=Max+extrude_depth
# RP
XRP=rad*xheight*(fhigh-1.)*2.
YRP=rad*yheight+rad/2.+(fwide-1.)*(rad+rad*yheight)*0.5
ZRP=extrude_depth*0.5
if shape==4:
# BC LEFT
XMnBL=Min
XMxBL=Max
YMnBL=Min
YMxBL=scaley+Max
ZMnBL=Min
ZMxBL=Max+extrude_depth
# BC BACK
XMnBBK=Min
XMxBBK=scalex+Max
YMnBBK=Min
YMxBBK=scaley+Max
ZMnBBK=Min
ZMxBBK=Max
# BC Bottom
XMnBBT=Min
XMxBBT=scalex+Max
YMnBBT=Min
YMxBBT=Max
ZMnBBT=Min
ZMxBBT=Max+extrude_depth
# BC Right
XMnBR=scalex+Min
XMxBR=scalex+Max
YMnBR=Min
YMxBR=scaley+Max
ZMnBR=Min
ZMxBR=Max+extrude_depth
# RP
XRP=scalex
YRP=scaley*0.5
ZRP=extrude_depth*0.5
#
total_length=(XMxBR-Max)-(XMnBL-Min)
BLeft=iNodes.getByBoundingBox(xMin=XMnBL,xMax=XMxBL,yMin=YMnBL,yMax=YMxBL,zMin=ZMnBL,zMax=ZMxBL)
BBack=iNodes.getByBoundingBox(xMin=XMnBBK,xMax=XMxBBK,yMin=YMnBBK,yMax=YMxBBK,zMin=ZMnBBK,zMax=ZMxBBK)
BBot=iNodes.getByBoundingBox(xMin=XMnBBT,xMax=XMxBBT,yMin=YMnBBT,yMax=YMxBBT,zMin=ZMnBBT,zMax=ZMxBBT)
BRight=iNodes.getByBoundingBox(xMin=XMnBR,xMax=XMxBR,yMin=YMnBR,yMax=YMxBR,zMin=ZMnBR,zMax=ZMxBR)
Ref1=VerAssembly.ReferencePoint(point=(XRP,YRP,ZRP))
#
BLregion=regionToolset.Region(nodes=BLeft)
BBregion=regionToolset.Region(nodes=BBot)
BBKregion=regionToolset.Region(nodes=BBack)
BRregion=regionToolset.Region(nodes=BRight)
VerModel.DisplacementBC(name='LeftX', createStepName='Initial',
region=BLregion, u1=0.0, u2=UNSET, u3=UNSET, ur1=UNSET, ur2=UNSET,
ur3=UNSET, amplitude=UNSET, fixed=OFF, distributionType=UNIFORM)
VerModel.DisplacementBC(name='BottomY', createStepName='Initial',
region=BBregion, u1=UNSET, u2=0.0, u3=UNSET, ur1=UNSET, ur2=UNSET,
ur3=UNSET, amplitude=UNSET, fixed=OFF, distributionType=UNIFORM)
VerModel.DisplacementBC(name='BackZ', createStepName='Initial',
region=BBKregion, u1=UNSET, u2=UNSET, u3=0.0, ur1=UNSET, ur2=UNSET,
ur3=UNSET, amplitude=UNSET, fixed=OFF, distributionType=UNIFORM)
#
id1=VerAssembly.features['RP-1'].id
RPoint=regionToolset.Region(referencePoints=(VerAssembly.referencePoints[id1],))
VerAssembly.Set(referencePoints=(VerAssembly.referencePoints[id1],), name='RPoint')
VerAssembly.Set(nodes=BRight, name='BRight')
VerModel.Equation(name='Constraint-1', terms=((1.0, 'BRight', 1), ( -1.0, 'RPoint', 1)))
VerModel.SmoothStepAmplitude(name='Load', timeSpan=STEP, data=((0.0, 0.0), (1.0, 1.0)))
VerModel.DisplacementBC(name='RPNode', createStepName='Load',
region=RPoint, u1=total_length*0.17, u2=0., u3=UNSET, ur1=UNSET, ur2=UNSET,
ur3=UNSET, amplitude='Load', fixed=OFF, distributionType=UNIFORM)

View file

@ -0,0 +1,750 @@
! This program generates a micro-strucutre mask and applies it to
! an existing mesh.
! J.Grogan 05/08/11
program Voronoi3DPost
!
! Parameters
parameter(max_elements=100000,max_cells=20000,max_fc=100,max_faces=10000)
parameter(max_elem_in_cell=50000,max_neigh_per_elem=6,max_neighbours=50)
!
! Variables
character(len=256)input
character(len=256)input2(2)
integer cell_stat(20000)
integer,allocatable,dimension(:)::closest
integer,allocatable,dimension(:)::num_ele_cell
integer,allocatable,dimension(:)::num_faces
integer,allocatable,dimension(:)::cell_status
integer,allocatable,dimension(:,:)::cell_ele
integer,dimension(max_elements)::num_neighbours
integer,dimension(max_elements,max_neighbours)::neighbour
integer mesh_type,mask_type,num_x,num_y,num_z,num_grains
double precision grain_length,rad_hard,rscale
double precision,allocatable,dimension(:,:)::distance
double precision,allocatable,dimension(:,:)::nbr_dist
double precision,allocatable,dimension(:,:)::cor_faces
double precision,dimension(max_elements)::cor_dist
double precision,allocatable,dimension(:,:)::ele_centroid
double precision,allocatable,dimension(:,:)::cell_centroid
double precision,allocatable,dimension(:,:,:)::face
!
! Mesh Type: 2 = 2D, 3 = 3D
mesh_type=3
! Mask Type: 1= Square, 2= Hexagon, 3= Dodec, 4=2D Voronoi, 5=3D Voronoi
mask_type=5
! Grain Length
Grain_length=0.025
! Num grains x
num_x=10
! Num grains y
num_y=10
! Num grains z
num_z=1
! Hardcore Voronoi Radius
rad_hard=0.00
num_grains=num_x*num_y*num_z
if(mask_type>3)then
! Create Tessellation
allocate(face(max_cells,max_fc,4),num_faces(max_cells),cell_centroid(max_cells,3))
call make_voronoi(mask_type,mesh_type,num_grains,num_x,rad_hard,grain_length)
call process_voronoi(face,num_faces,cell_centroid,num_cells,cell_stat)
else
! Generate Centroids and faces for other geometries
icount=1
num_cells=num_grains
allocate(face(num_cells,6,4),num_faces(num_cells),cell_centroid(num_cells,3))
do i=1,num_x
do j=1,num_y
do k=1,num_z
if(mask_type==1)then
call make_square(i,j,k,grain_length,num_faces(icount), &
& face(icount,:,:),cell_centroid(icount,:),mesh_type)
elseif(mask_type==2)then
call make_hexagon(i,j,k,grain_length,num_faces(icount), &
& face(icount,:,:),cell_centroid(icount,:),mesh_type)
else
if(mod(j,2)==0)then
cell_centroid(icount,1)=2.*(i-1)*Grain_length*sqrt(2.)+&
&sqrt(2.)*Grain_length
cell_centroid(icount,3)=2.*(k-1)*Grain_length*sqrt(2.)+&
&Grain_length*sqrt(2.)
else
cell_centroid(icount,1)=2.*(i-1)*Grain_length*sqrt(2.)
cell_centroid(icount,3)=2.*(k-1)*Grain_length*sqrt(2.)
endif
cell_centroid(icount,2)=2.*(j-1)*Grain_length
endif
icount=icount+1
enddo
enddo
enddo
endif
!
allocate(ele_centroid(max_elements,3))
! Get element centroids
call elem_centroids(num_elements,ele_centroid,mesh_type)
!
! Get neighbouring elements
allocate(nbr_dist(max_elements,max_neighbours))
do i=1,num_elements
icount=1
do j=1,num_elements
if(icount>max_neighbours)then
rmaxdist=0.
do k=1,max_neighbours
if(nbr_dist(i,k)>rmaxdist)then
rmaxdist=nbr_dist(i,k)
index_max_dist=k
endif
enddo
endif
cent1x=ele_centroid(i,1)
cent1y=ele_centroid(i,2)
cent1z=ele_centroid(i,3)
cent2x=ele_centroid(j,1)
cent2y=ele_centroid(j,2)
cent2z=ele_centroid(j,3)
dist=sqrt((cent1x-cent2x)*(cent1x-cent2x)+(cent1y-cent2y)*(cent1y-cent2y)&
&+(cent1z-cent2z)*(cent1z-cent2z))
if(icount>max_neighbours)then
if(dist<rmaxdist)then
nbr_dist(i,index_max_dist)=dist
neighbour(i,index_max_dist)=j
endif
else
nbr_dist(i,j)=dist
neighbour(i,j)=j
endif
icount=icount+1
enddo
print *,float(i)/float(num_elements)
enddo
deallocate(nbr_dist)
!
! Get corrosion surface distances
open(unit=22,file='CorSurf.dat',status='unknown')
allocate(cor_faces(max_faces,3))
ierr=0
inum_faces=1
do while (ierr==0)
read(22,*,iostat=ierr)cor_faces(inum_faces,1),cor_faces(inum_faces,2),&
&cor_faces(inum_faces,3)
if(ierr==0)inum_faces=inum_faces+1
enddo
close(unit=22)
do i=1,num_elements
centx=ele_centroid(i,1)
centy=ele_centroid(i,2)
centz=ele_centroid(i,3)
distmin=1000.
do j=1,inum_faces-1
facex=cor_faces(j,1)
facey=cor_faces(j,2)
facez=cor_faces(j,3)
dist=sqrt((centx-facex)*(centx-facex)+(centy-facey)*(centy-facey)&
&+(centz-facez)*(centz-facez))
if(dist<distmin)distmin=dist
enddo
cor_dist(i)=distmin
enddo
deallocate(cor_faces)
!
! Find closest cell to element centroid
allocate(closest(max_elements))
if(mask_type==5)then
do i=1,num_elements
centx=ele_centroid(i,1)
centy=ele_centroid(i,2)
centz=ele_centroid(i,3)
do j=1,num_cells
if(num_faces(j)<3)then
print *,'warning',i,j,num_faces(j)
cycle
endif
if(cell_stat(j)==1)cycle
icheck=0
do k=1,num_faces(j)
rnorx=face(j,k,1)
rnory=face(j,k,2)
rnorz=face(j,k,3)
roff=face(j,k,4)
dotprod=centx*rnorx+centy*rnory+centz*rnorz+roff
if(dotprod<0.)then
icheck=1
exit
endif
enddo
if(icheck==0)then
closest(i)=j
endif
enddo
enddo
else
do i=1,num_elements
centx=ele_centroid(i,1)
centy=ele_centroid(i,2)
do j=1,num_cells
if(cell_stat(j)==1)cycle
cellx=cell_centroid(j,1)
celly=cell_centroid(j,2)
icheck=0
do k=1,num_faces(j)
fx1=face(j,k,1)
fx2=face(j,k,2)
fy1=face(j,k,3)
fy2=face(j,k,4)
dcell=(fx2-fx1)*(celly-fy1)-(fy2-fy1)*(cellx-fx1)
dele=(fx2-fx1)*(centy-fy1)-(fy2-fy1)*(centx-fx1)
if(dcell<0.)then
if(dele>=0.)icheck=1
else
if(dele<0.)icheck=1
endif
if(icheck==1)exit
enddo
if(icheck==0)then
closest(i)=j
endif
enddo
enddo
endif
!
allocate(num_ele_cell(num_cells),cell_ele(num_cells,max_elem_in_cell))
! Find each element in a cell
do i=1,num_cells
num_ele_cell(i)=0
do j=1,num_elements
if(closest(j)==i)then
num_ele_cell(i)=num_ele_cell(i)+1
cell_ele(i,num_ele_cell(i))=j
endif
enddo
enddo
!
!
allocate(distance(num_cells,num_elements))
! Find min distance between element centroid and cell faces/hyperplanes
do i=1,num_cells
if(i==1406) print *,num_faces(i)
do j=1,num_ele_cell(i)
centx=ele_centroid(cell_ele(i,j),1)
centy=ele_centroid(cell_ele(i,j),2)
centz=ele_centroid(cell_ele(i,j),3)
distmin=1000.
if(mask_type==5)then
do k=1,num_faces(i)
rnorx=face(i,k,1)
rnory=face(i,k,2)
rnorz=face(i,k,3)
roff=face(i,k,4)
dotprod=abs(centx*rnorx+centy*rnory+centz*rnorz+roff)
if(dotprod<distmin)distmin=dotprod
enddo
else
do k=1,num_faces(i)
x1=face(i,k,1)
x2=face(i,k,2)
y1=face(i,k,3)
y2=face(i,k,4)
dotprod=abs((x2-x1)*(y1-centy)-(x1-centx)*(y2-y1))
dotprod=dotprod/(sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)))
if(dotprod<distmin)distmin=dotprod
enddo
endif
distance(i,j)=distmin
enddo
enddo
!
! Write Element Sets
rewind(10)
open(unit=13,file='GeomGenINP.inp',status='unknown')
input2(1)='**'
do while (index(input2(1),'*End Part')==0)
read(10,'(a)')input2(2)
write(13,'(a)')input2(1)
input2(1)=input2(2)
enddo
do i=1,num_cells
if(num_ele_cell(i)==0)cycle
write(13,*)'*Elset,elset=ele',i
icheck=1
do j=1,num_ele_cell(i)
if(icheck==1)then
if(num_ele_cell(i)>1)then
write(13,'(i6)',advance='no')cell_ele(i,j)
else
write(13,'(i6)')cell_ele(i,j)
endif
elseif(icheck==num_ele_cell(i))then
write(13,'(a1,i6)')',',cell_ele(i,j)
else
if(mod(icheck,15)==0)then
write(13,'(a1,i6)')',',cell_ele(i,j)
else
write(13,'(a1,i6)',advance='no')',',cell_ele(i,j)
endif
endif
icheck=icheck+1
enddo
if(iana_type==1)write(19,*)'*Solid Section,elset=ele',i,'Boundary,material=Mat',i
enddo
write(13,*)'**'
do while (index(input2(1),'*End Assembly')==0)
read(10,'(a)')input2(2)
write(13,'(a)')input2(1)
input2(1)=input2(2)
enddo
write(13,'(a)')'*End Assembly'
write(13,*)'*INITIAL CONDITIONS,TYPE=SOLUTION'
do i=1,num_cells
if(num_ele_cell(i)==0)cycle
do j=1,num_ele_cell(i)
write(13,'(3(a,i6),2(a,f18.6),3(i6,a))')'Assembly.CorPart.',cell_ele(i,j),',' &
& ,cell_ele(i,j),',',max_neighbours,',',distance(i,j),',',cor_dist(cell_ele(i,j)) &
& ,0,',',0,',',0,','
write(13,'(8(i6,a))')0,',',0,',',0,',',0,',',0,',',0,',',0,',',1,','
do k=1, max_neighbours
if(mod(k,8)/=0)then
if(k/=max_neighbours)then
write(13,'(i6,a)',advance='no')neighbour(cell_ele(i,j),k),','
else
write(13,'(i6)')neighbour(cell_ele(i,j),k)
endif
else
if(k/=max_neighbours)then
write(13,'(i6,a)')neighbour(cell_ele(i,j),k),','
else
write(13,'(i6)')neighbour(cell_ele(i,j),k)
endif
endif
enddo
enddo
enddo
ierr=0
do while (ierr==0)
read(10,'(a)',iostat=ierr)input2(1)
if(ierr==0)write(13,'(a)')input2(1)
enddo
end program
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Generate Voronoi Tesselation Using QHULL
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine make_voronoi(mask_type,mesh_type,num_grains,num_x,rad_hard,grain_length)
integer mesh_type,mask_type,num_grains
integer seed(1)
double precision grain_length,rad_hard,rscale
if(mesh_type==2)mask_type=4
! Write QHull input file
open(unit=20,file='qhullin.dat',status='unknown')
write(20,*)mask_type-2
if(mask_type==5)write(20,*)num_grains*27
if(mask_type==4)write(20,*)num_grains*9
seed=1557
rscale=float(num_x)*Grain_Length
call random_seed(put=seed)
do i=1,num_grains
call random_number(xcor)
call random_number(ycor)
if(mask_type==5)call random_number(zcor)
xcor=xcor*rscale
ycor=ycor*rscale
if(mask_type==5)zcor=zcor*rscale
if(mask_type==4)then
write(20,*)xcor,ycor
write(20,*)xcor,ycor+rscale
write(20,*)xcor,ycor-rscale
write(20,*)xcor+rscale,ycor
write(20,*)xcor-rscale,ycor
write(20,*)xcor+rscale,ycor+rscale
write(20,*)xcor-rscale,ycor-rscale
write(20,*)xcor+rscale,ycor-rscale
write(20,*)xcor-rscale,ycor+rscale
elseif(mask_type==5)then
write(20,*)xcor,ycor,zcor
write(20,*)xcor+rscale,ycor,zcor
write(20,*)xcor-rscale,ycor,zcor
write(20,*)xcor,ycor+rscale,zcor
write(20,*)xcor,ycor-rscale,zcor
write(20,*)xcor+rscale,ycor+rscale,zcor
write(20,*)xcor-rscale,ycor-rscale,zcor
write(20,*)xcor+rscale,ycor-rscale,zcor
write(20,*)xcor-rscale,ycor+rscale,zcor
write(20,*)xcor,ycor,zcor+rscale
write(20,*)xcor+rscale,ycor,zcor+rscale
write(20,*)xcor-rscale,ycor,zcor+rscale
write(20,*)xcor,ycor+rscale,zcor+rscale
write(20,*)xcor,ycor-rscale,zcor+rscale
write(20,*)xcor+rscale,ycor+rscale,zcor+rscale
write(20,*)xcor-rscale,ycor-rscale,zcor+rscale
write(20,*)xcor+rscale,ycor-rscale,zcor+rscale
write(20,*)xcor-rscale,ycor+rscale,zcor+rscale
write(20,*)xcor,ycor,zcor-rscale
write(20,*)xcor+rscale,ycor,zcor-rscale
write(20,*)xcor-rscale,ycor,zcor-rscale
write(20,*)xcor,ycor+rscale,zcor-rscale
write(20,*)xcor,ycor-rscale,zcor-rscale
write(20,*)xcor+rscale,ycor+rscale,zcor-rscale
write(20,*)xcor-rscale,ycor-rscale,zcor-rscale
write(20,*)xcor+rscale,ycor-rscale,zcor-rscale
write(20,*)xcor-rscale,ycor+rscale,zcor-rscale
endif
enddo
close(20)
call system('qvoronoi.exe TI qhullin.dat o Fi TO qhullout.dat')
end subroutine
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Process Voronoi Tesselation - Return Arrays of Cell Faces and Centroids
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine process_voronoi(face_sub,num_faces_sub,cell_centroid,num_cells,cell_stat)
!
! Variables
character(len=320)full_line
character(len=320)test_string
character(len=256)input
character(len=256)input2(2)
integer seed (1)
integer cell_stat(20000)
integer,allocatable,dimension(:)::num_verts
integer,allocatable,dimension(:)::num_cell_hyp
integer,allocatable,dimension(:)::numverts
integer,dimension(20000)::num_faces_sub
integer,allocatable,dimension(:,:)::num_hyp_verts
integer,allocatable,dimension(:,:)::vert_list
integer,allocatable,dimension(:,:)::hyp_list
integer,allocatable,dimension(:,:)::facet
integer max_vc,max_hc,max_vh
double precision,allocatable,dimension(:)::xv_cor
double precision,allocatable,dimension(:)::yv_cor
double precision,allocatable,dimension(:)::zv_cor
double precision,allocatable,dimension(:)::offset
double precision,allocatable,dimension(:,:)::cor
double precision,allocatable,dimension(:,:)::ele_centroid
double precision,dimension(20000,3)::cell_centroid
double precision,dimension(20000,100,4)::face_sub
!
! Parameters
parameter(max_vc=100,max_hc=100,max_vh=50)
!
open(unit=21,file='qhullout.dat',status='unknown')
!
! Allocate Arrays
read(21,*)idimension
read(21,*)num_total_verts,num_cells
allocate(num_verts(num_cells))
allocate(xv_cor(num_total_verts),yv_cor(num_total_verts))
if(idimension==3)allocate(zv_cor(num_total_verts))
allocate(vert_list(num_cells,max_vc))
!
! Read in all vertice co-ordinates
do i=1,num_total_verts
if(idimension==2)read(21,*)xv_cor(i),yv_cor(i)
if(idimension==3)read(21,*)xv_cor(i),yv_cor(i),zv_cor(i)
enddo
!
! Read in vertice labels for each voronoi cell
do i=1,num_cells
read(21,*)num_verts(i)
backspace(21)
if(num_verts(i)>9)then
read(21,'(i3,a320)')idummy,full_line
else
read(21,'(i2,a320)')idummy,full_line
endif
ileft=1
num_points=1
do iright=1,320
test_string=full_line(iright:iright)
if((test_string==' ').or.(iright==320))then
read(full_line(ileft:iright-1),'(i6)')vert_list(i,num_points)
if(num_points==num_verts(i))exit
ileft=iright+1
num_points=num_points+1
endif
enddo
do j=1,num_points-1
if(vert_list(i,j)==0)cell_stat(i)=1
enddo
enddo
if(idimension==3)then
!
! Read in bounded hyperplane cell labels and co-ordinates
read(21,*)num_hyp
allocate(facet(2,num_hyp),cor(3,num_hyp),offset(num_hyp))
allocate(hyp_list(num_cells,num_hyp),num_cell_hyp(num_cells))
!
do i=1,num_hyp
read(21,*)dummy,facet(1,i),facet(2,i),cor(1,i),cor(2,i),cor(3,i),offset(i)
enddo
!
! Determine hyperplanes of each cell
do i=1,num_cells
num_hy=1
do j=1,num_hyp
if((facet(1,j)==i-1).or.(facet(2,j)==i-1))then
hyp_list(i,num_hy)=j
num_cell_hyp(i)=num_hy
num_hy=num_hy+1
endif
enddo
enddo
!
! Store hyperplane info in convenient format
do i=1,num_cells
num_faces_sub(i)=num_cell_hyp(i)
do j=1,num_cell_hyp(i)
face_sub(i,j,1)=cor(1,hyp_list(i,j))
face_sub(i,j,2)=cor(2,hyp_list(i,j))
face_sub(i,j,3)=cor(3,hyp_list(i,j))
face_sub(i,j,4)=offset(hyp_list(i,j))
enddo
enddo
else
do i=1,num_cells
num_faces_sub(i)=num_verts(i)
do j=1,num_verts(i)
x2=xv_cor(vert_list(i,j)+1)
y2=yv_cor(vert_list(i,j)+1)
if(j==1)then
x1=xv_cor(vert_list(i,num_verts(i))+1)
y1=yv_cor(vert_list(i,num_verts(i))+1)
else
x1=xv_cor(vert_list(i,j-1)+1)
y1=yv_cor(vert_list(i,j-1)+1)
endif
face_sub(i,j,1)=x1
face_sub(i,j,2)=x2
face_sub(i,j,3)=y1
face_sub(i,j,4)=y2
enddo
enddo
endif
!
! Get cell centroid
do i=1,num_cells
centroidx=0.
centroidy=0.
centroidz=0.
do j=1,num_verts(i)
centroidx=centroidx+xv_cor(vert_list(i,j)+1)
centroidy=centroidy+yv_cor(vert_list(i,j)+1)
if(idimension==3)centroidz=centroidz+zv_cor(vert_list(i,j)+1)
enddo
cell_centroid(i,1)=centroidx/float(num_verts(i))
cell_centroid(i,2)=centroidy/float(num_verts(i))
if(idimension==3)then
cell_centroid(i,3)=centroidz/float(num_verts(i))
else
cell_centroid(i,3)=0.d0
endif
enddo
if(idimension==3)then
! Flip hyperplane normal if it points away from cell centroid
do i=1,num_cells
centx=cell_centroid(i,1)
centy=cell_centroid(i,2)
centz=cell_centroid(i,3)
distmin=1000.
do k=1,num_faces_sub(i)
rnorx=face_sub(i,k,1)
rnory=face_sub(i,k,2)
rnorz=face_sub(i,k,3)
roff=face_sub(i,k,4)
dotprod=centx*rnorx+centy*rnory+centz*rnorz+roff
if(dotprod<0.)then
face_sub(i,k,1)=-face_sub(i,k,1)
face_sub(i,k,2)=-face_sub(i,k,2)
face_sub(i,k,3)=-face_sub(i,k,3)
face_sub(i,k,4)=-face_sub(i,k,4)
endif
enddo
enddo
endif
close(unit=21)
deallocate(num_verts,xv_cor,yv_cor)
if(idimension==3)deallocate(zv_cor,facet,cor,offset,hyp_list,num_cell_hyp)
end subroutine
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Make Squares - Return Arrays of Cell Faces and Centroids
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine make_square(i,j,k,grain_length,num_faces,face,cell_centroid,mesh_type)
!
integer num_faces,m
double precision grain_length,centrex,centrey,centrez,rsign,xnor,ynor,znor
double precision rdist
double precision,dimension(3)::cell_centroid
double precision,dimension(6,4)::face
!
!
num_faces=4
centrex=(i-1)*Grain_length+Grain_length/2.d0
centrey=(j-1)*Grain_length+Grain_length/2.d0
if(mesh_type==3)then
centrez=(k-1)*Grain_length+Grain_length/2.d0
else
centrez=0.d0
endif
!
! Centroid
cell_centroid(1)=centrex
cell_centroid(2)=centrey
cell_centroid(3)=centrez
!
! Faces
do m=1,num_faces
rsign=1.d0
xnor=0.d0
ynor=0.d0
znor=0.d0
unitx=grain_length/2.d0
unity=grain_length/2.d0
if(mod(m,2)==0)rsign=-1.d0
if(m<=2)then
x1=centrex+rsign*unitx
x2=centrex+rsign*unitx
y1=centrey+unity
y2=centrey-unity
else
x1=centrex+unitx
x2=centrex-unitx
y1=centrey+rsign*unity
y2=centrey+rsign*unity
endif
face(m,1)=x1
face(m,2)=x2
face(m,3)=y1
face(m,4)=y2
enddo
end Subroutine
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Make Hexagons - Return Arrays of Cell Faces and Centroids
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine make_hexagon(i,j,k,grain_length,num_faces,face,cell_centroid,mesh_type)
integer num_faces,m
double precision grain_length,centrex,centrey,centrez,rsign,xnor,ynor,znor
double precision rdist
double precision,dimension(3)::cell_centroid
double precision,dimension(6,4)::face
!
!
num_faces=6
if(mod(j,2)==0)then
centrex=(i-1)*sqrt(3.d0)*Grain_length+sqrt(3.d0)*Grain_length/2.d0
else
centrex=(i-1)*sqrt(3.)*Grain_length
endif
centrey=(j-1)*1.5d0*Grain_length
if(mesh_type==3)then
centrez=(k-1)*Grain_length
else
centrez=0.d0
endif
!
! Centroid
cell_centroid(1)=centrex
cell_centroid(2)=centrey
cell_centroid(3)=centrez
!
! Faces
do m=1,num_faces
rsign=1.d0
rsign2=1.d0
xnor=0.d0
ynor=0.d0
znor=0.d0
unity=0.5d0*grain_length
unitx=(sqrt(3.d0)/2.d0)*grain_length
if(mod(m,2)==0)rsign=-1.d0
if(m<=2)then
x1=centrex+rsign*unitx
x2=centrex+rsign*unitx
y1=centrey+unity
y2=centrey-unity
elseif(m>2.and.m<=4)then
x1=centrex
x2=centrex+unitx
y1=centrey+rsign*unity*2.d0
y2=centrey+rsign*unity
else
x1=centrex
x2=centrex-unitx
y1=centrey+rsign*unity*2.d0
y2=centrey+rsign*unity
endif
face(m,1)=x1
face(m,2)=x2
face(m,3)=y1
face(m,4)=y2
enddo
end Subroutine
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Get Element Centroids
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine elem_centroids(ne,ele_centroid,mesh_type)
!
! Parameters
parameter(max_nodes=1000000,max_elements=100000,max_node_in_elem=8)
!
! Variables
character(len=256)input
integer,dimension(max_elements,max_node_in_elem)::elements
double precision,dimension(max_nodes,3)::nodes
double precision,dimension(max_elements,3)::ele_centroid
!
! Open Input File and read node and element co-ordinates
open(unit=10,file='GeomGenTemp.inp',status='unknown')
do while (index(input,'*Node')==0)
read(10,'(a)')input
end do
nn=0
do while(1==1)
read(10,'(a)')input
if(index(input,'*')==0)then
backspace(10)
nn=nn+1
if(mesh_type==3)then
read(10,*)dummy,nodes(nn,1),nodes(nn,2),nodes(nn,3)
else
read(10,*)dummy,nodes(nn,1),nodes(nn,2)
endif
else
if(mesh_type==2)then
nele_type=4
else
if(index(input,'C3D8')/=0)nele_type=8
if(index(input,'C3D4')/=0)nele_type=4
endif
exit
endif
end do
ne=0
do while(1==1)
read(10,'(a)')input
if(index(input,'*')==0)then
backspace(10)
ne=ne+1
if(nele_type==8)then
read(10,*)dummy,elements(ne,1),elements(ne,2),elements(ne,3),elements(ne,4)&
& ,elements(ne,5),elements(ne,6),elements(ne,7),elements(ne,8)
elseif(nele_type==4)then
read(10,*)dummy,elements(ne,1),elements(ne,2),elements(ne,3),elements(ne,4)
endif
else
exit
endif
end do
!
! Get element centroid
do i=1,ne
centroidx=0.d0
centroidy=0.d0
centroidz=0.d0
do j=1,nele_type
centroidx=centroidx+nodes(elements(i,j),1)
centroidy=centroidy+nodes(elements(i,j),2)
if(mesh_type==3)centroidz=centroidz+nodes(elements(i,j),3)
enddo
ele_centroid(i,1)=centroidx/float(nele_type)
ele_centroid(i,2)=centroidy/float(nele_type)
if(mesh_type==3)ele_centroid(i,3)=centroidz/float(nele_type)
enddo
end subroutine

View file

@ -0,0 +1,200 @@
! This program generates a micro-strucutre mask and applies it to
! an existing mesh.
! J.Grogan 05/08/11
program Corrosion_Preprocessor
!
! Parameters
parameter(max_elements=100000,max_cells=20000,max_fc=100,max_faces=10000)
parameter(max_elem_in_cell=50000,max_neigh_per_elem=6,max_neighbours=50)
!
! Variables
character(len=256)input
character(len=256)input2(2)
integer,allocatable,dimension(:)::num_faces
integer,dimension(max_elements,max_neighbours)::neighbour
integer mesh_type
double precision,allocatable,dimension(:,:)::distance
double precision,allocatable,dimension(:,:)::nbr_dist
double precision,allocatable,dimension(:,:)::cor_faces
double precision,dimension(max_elements)::cor_dist
double precision,allocatable,dimension(:,:)::ele_centroid
!
! Mesh Type: 2 = 2D, 3 = 3D
mesh_type=3
!
allocate(ele_centroid(max_elements,3))
! Get element centroids
call elem_centroids(num_elements,ele_centroid,mesh_type)
!
! Get neighbouring elements
allocate(nbr_dist(max_elements,max_neighbours))
do i=1,num_elements
icount=1
do j=1,num_elements
if(icount>max_neighbours)then
rmaxdist=0.
do k=1,max_neighbours
if(nbr_dist(i,k)>rmaxdist)then
rmaxdist=nbr_dist(i,k)
index_max_dist=k
endif
enddo
endif
cent1x=ele_centroid(i,1)
cent1y=ele_centroid(i,2)
cent1z=ele_centroid(i,3)
cent2x=ele_centroid(j,1)
cent2y=ele_centroid(j,2)
cent2z=ele_centroid(j,3)
dist=sqrt((cent1x-cent2x)*(cent1x-cent2x)+(cent1y-cent2y)*(cent1y-cent2y)&
&+(cent1z-cent2z)*(cent1z-cent2z))
if(icount>max_neighbours)then
if(dist<rmaxdist)then
nbr_dist(i,index_max_dist)=dist
neighbour(i,index_max_dist)=j
endif
else
nbr_dist(i,j)=dist
neighbour(i,j)=j
endif
icount=icount+1
enddo
print *,float(i)/float(num_elements)
enddo
deallocate(nbr_dist)
!
! Get corrosion surface distances
open(unit=22,file='CorSurf.dat',status='unknown')
allocate(cor_faces(max_faces,3))
ierr=0
inum_faces=1
do while (ierr==0)
read(22,*,iostat=ierr)cor_faces(inum_faces,1),cor_faces(inum_faces,2),&
&cor_faces(inum_faces,3)
if(ierr==0)inum_faces=inum_faces+1
enddo
close(unit=22)
do i=1,num_elements
centx=ele_centroid(i,1)
centy=ele_centroid(i,2)
centz=ele_centroid(i,3)
distmin=1000.
do j=1,inum_faces-1
facex=cor_faces(j,1)
facey=cor_faces(j,2)
facez=cor_faces(j,3)
dist=sqrt((centx-facex)*(centx-facex)+(centy-facey)*(centy-facey)&
&+(centz-facez)*(centz-facez))
if(dist<distmin)distmin=dist
enddo
cor_dist(i)=distmin
enddo
deallocate(cor_faces)
!
rewind(10)
open(unit=13,file='GeomGenINP.inp',status='unknown')
input2(1)='**'
do while (index(input2(1),'*End Assembly')==0)
read(10,'(a)')input2(2)
write(13,'(a)')input2(1)
input2(1)=input2(2)
enddo
write(13,'(a)')'*End Assembly'
write(13,*)'*INITIAL CONDITIONS,TYPE=SOLUTION'
do i=1,num_elements
write(13,'(3(a,i6),2(a,f18.6),3(i6,a))')'Assembly.CorPart.',i,',' &
& ,i,',',max_neighbours,',',0.,',',cor_dist(i,j),0,',',1.,',',0,','
do k=1, max_neighbours
if(mod(k,8)/=0)then
if(k/=max_neighbours)then
write(13,'(i6,a)',advance='no')neighbour(i,k),','
else
write(13,'(i6)')neighbour(i,k)
endif
else
if(k/=max_neighbours)then
write(13,'(i6,a)')neighbour(i,k),','
else
write(13,'(i6)')neighbour(i,k)
endif
endif
enddo
enddo
ierr=0
do while (ierr==0)
read(10,'(a)',iostat=ierr)input2(1)
if(ierr==0)write(13,'(a)')input2(1)
enddo
end program
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Get Element Centroids
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine elem_centroids(ne,ele_centroid,mesh_type)
!
! Parameters
parameter(max_nodes=1000000,max_elements=100000,max_node_in_elem=8)
!
! Variables
character(len=256)input
integer,dimension(max_elements,max_node_in_elem)::elements
double precision,dimension(max_nodes,3)::nodes
double precision,dimension(max_elements,3)::ele_centroid
!
! Open Input File and read node and element co-ordinates
open(unit=10,file='GeomGenTemp.inp',status='unknown')
do while (index(input,'*Node')==0)
read(10,'(a)')input
end do
nn=0
do while(1==1)
read(10,'(a)')input
if(index(input,'*')==0)then
backspace(10)
nn=nn+1
if(mesh_type==3)then
read(10,*)dummy,nodes(nn,1),nodes(nn,2),nodes(nn,3)
else
read(10,*)dummy,nodes(nn,1),nodes(nn,2)
endif
else
if(mesh_type==2)then
nele_type=4
else
if(index(input,'C3D8')/=0)nele_type=8
if(index(input,'C3D4')/=0)nele_type=4
endif
exit
endif
end do
ne=0
do while(1==1)
read(10,'(a)')input
if(index(input,'*')==0)then
backspace(10)
ne=ne+1
if(nele_type==8)then
read(10,*)dummy,elements(ne,1),elements(ne,2),elements(ne,3),elements(ne,4)&
& ,elements(ne,5),elements(ne,6),elements(ne,7),elements(ne,8)
elseif(nele_type==4)then
read(10,*)dummy,elements(ne,1),elements(ne,2),elements(ne,3),elements(ne,4)
endif
else
exit
endif
end do
!
! Get element centroid
do i=1,ne
centroidx=0.d0
centroidy=0.d0
centroidz=0.d0
do j=1,nele_type
centroidx=centroidx+nodes(elements(i,j),1)
centroidy=centroidy+nodes(elements(i,j),2)
if(mesh_type==3)centroidz=centroidz+nodes(elements(i,j),3)
enddo
ele_centroid(i,1)=centroidx/float(nele_type)
ele_centroid(i,2)=centroidy/float(nele_type)
if(mesh_type==3)ele_centroid(i,3)=centroidz/float(nele_type)
enddo
end subroutine

View file

@ -0,0 +1,750 @@
! This program generates a micro-strucutre mask and applies it to
! an existing mesh.
! J.Grogan 05/08/11
program Voronoi3DPost
!
! Parameters
parameter(max_elements=100000,max_cells=20000,max_fc=100,max_faces=10000)
parameter(max_elem_in_cell=50000,max_neigh_per_elem=6,max_neighbours=50)
!
! Variables
character(len=256)input
character(len=256)input2(2)
integer cell_stat(20000)
integer,allocatable,dimension(:)::closest
integer,allocatable,dimension(:)::num_ele_cell
integer,allocatable,dimension(:)::num_faces
integer,allocatable,dimension(:)::cell_status
integer,allocatable,dimension(:,:)::cell_ele
integer,dimension(max_elements)::num_neighbours
integer,dimension(max_elements,max_neighbours)::neighbour
integer mesh_type,mask_type,num_x,num_y,num_z,num_grains
double precision grain_length,rad_hard,rscale
double precision,allocatable,dimension(:,:)::distance
double precision,allocatable,dimension(:,:)::nbr_dist
double precision,allocatable,dimension(:,:)::cor_faces
double precision,dimension(max_elements)::cor_dist
double precision,allocatable,dimension(:,:)::ele_centroid
double precision,allocatable,dimension(:,:)::cell_centroid
double precision,allocatable,dimension(:,:,:)::face
!
! Mesh Type: 2 = 2D, 3 = 3D
mesh_type=3
! Mask Type: 1= Square, 2= Hexagon, 3= Dodec, 4=2D Voronoi, 5=3D Voronoi
mask_type=5
! Grain Length
Grain_length=0.025
! Num grains x
num_x=10
! Num grains y
num_y=10
! Num grains z
num_z=1
! Hardcore Voronoi Radius
rad_hard=0.00
num_grains=num_x*num_y*num_z
if(mask_type>3)then
! Create Tessellation
allocate(face(max_cells,max_fc,4),num_faces(max_cells),cell_centroid(max_cells,3))
call make_voronoi(mask_type,mesh_type,num_grains,num_x,rad_hard,grain_length)
call process_voronoi(face,num_faces,cell_centroid,num_cells,cell_stat)
else
! Generate Centroids and faces for other geometries
icount=1
num_cells=num_grains
allocate(face(num_cells,6,4),num_faces(num_cells),cell_centroid(num_cells,3))
do i=1,num_x
do j=1,num_y
do k=1,num_z
if(mask_type==1)then
call make_square(i,j,k,grain_length,num_faces(icount), &
& face(icount,:,:),cell_centroid(icount,:),mesh_type)
elseif(mask_type==2)then
call make_hexagon(i,j,k,grain_length,num_faces(icount), &
& face(icount,:,:),cell_centroid(icount,:),mesh_type)
else
if(mod(j,2)==0)then
cell_centroid(icount,1)=2.*(i-1)*Grain_length*sqrt(2.)+&
&sqrt(2.)*Grain_length
cell_centroid(icount,3)=2.*(k-1)*Grain_length*sqrt(2.)+&
&Grain_length*sqrt(2.)
else
cell_centroid(icount,1)=2.*(i-1)*Grain_length*sqrt(2.)
cell_centroid(icount,3)=2.*(k-1)*Grain_length*sqrt(2.)
endif
cell_centroid(icount,2)=2.*(j-1)*Grain_length
endif
icount=icount+1
enddo
enddo
enddo
endif
!
allocate(ele_centroid(max_elements,3))
! Get element centroids
call elem_centroids(num_elements,ele_centroid,mesh_type)
!
! Get neighbouring elements
allocate(nbr_dist(max_elements,max_neighbours))
do i=1,num_elements
icount=1
do j=1,num_elements
if(icount>max_neighbours)then
rmaxdist=0.
do k=1,max_neighbours
if(nbr_dist(i,k)>rmaxdist)then
rmaxdist=nbr_dist(i,k)
index_max_dist=k
endif
enddo
endif
cent1x=ele_centroid(i,1)
cent1y=ele_centroid(i,2)
cent1z=ele_centroid(i,3)
cent2x=ele_centroid(j,1)
cent2y=ele_centroid(j,2)
cent2z=ele_centroid(j,3)
dist=sqrt((cent1x-cent2x)*(cent1x-cent2x)+(cent1y-cent2y)*(cent1y-cent2y)&
&+(cent1z-cent2z)*(cent1z-cent2z))
if(icount>max_neighbours)then
if(dist<rmaxdist)then
nbr_dist(i,index_max_dist)=dist
neighbour(i,index_max_dist)=j
endif
else
nbr_dist(i,j)=dist
neighbour(i,j)=j
endif
icount=icount+1
enddo
print *,float(i)/float(num_elements)
enddo
deallocate(nbr_dist)
!
! Get corrosion surface distances
open(unit=22,file='CorSurf.dat',status='unknown')
allocate(cor_faces(max_faces,3))
ierr=0
inum_faces=1
do while (ierr==0)
read(22,*,iostat=ierr)cor_faces(inum_faces,1),cor_faces(inum_faces,2),&
&cor_faces(inum_faces,3)
if(ierr==0)inum_faces=inum_faces+1
enddo
close(unit=22)
do i=1,num_elements
centx=ele_centroid(i,1)
centy=ele_centroid(i,2)
centz=ele_centroid(i,3)
distmin=1000.
do j=1,inum_faces-1
facex=cor_faces(j,1)
facey=cor_faces(j,2)
facez=cor_faces(j,3)
dist=sqrt((centx-facex)*(centx-facex)+(centy-facey)*(centy-facey)&
&+(centz-facez)*(centz-facez))
if(dist<distmin)distmin=dist
enddo
cor_dist(i)=distmin
enddo
deallocate(cor_faces)
!
! Find closest cell to element centroid
allocate(closest(max_elements))
if(mask_type==5)then
do i=1,num_elements
centx=ele_centroid(i,1)
centy=ele_centroid(i,2)
centz=ele_centroid(i,3)
do j=1,num_cells
if(num_faces(j)<3)then
print *,'warning',i,j,num_faces(j)
cycle
endif
if(cell_stat(j)==1)cycle
icheck=0
do k=1,num_faces(j)
rnorx=face(j,k,1)
rnory=face(j,k,2)
rnorz=face(j,k,3)
roff=face(j,k,4)
dotprod=centx*rnorx+centy*rnory+centz*rnorz+roff
if(dotprod<0.)then
icheck=1
exit
endif
enddo
if(icheck==0)then
closest(i)=j
endif
enddo
enddo
else
do i=1,num_elements
centx=ele_centroid(i,1)
centy=ele_centroid(i,2)
do j=1,num_cells
if(cell_stat(j)==1)cycle
cellx=cell_centroid(j,1)
celly=cell_centroid(j,2)
icheck=0
do k=1,num_faces(j)
fx1=face(j,k,1)
fx2=face(j,k,2)
fy1=face(j,k,3)
fy2=face(j,k,4)
dcell=(fx2-fx1)*(celly-fy1)-(fy2-fy1)*(cellx-fx1)
dele=(fx2-fx1)*(centy-fy1)-(fy2-fy1)*(centx-fx1)
if(dcell<0.)then
if(dele>=0.)icheck=1
else
if(dele<0.)icheck=1
endif
if(icheck==1)exit
enddo
if(icheck==0)then
closest(i)=j
endif
enddo
enddo
endif
!
allocate(num_ele_cell(num_cells),cell_ele(num_cells,max_elem_in_cell))
! Find each element in a cell
do i=1,num_cells
num_ele_cell(i)=0
do j=1,num_elements
if(closest(j)==i)then
num_ele_cell(i)=num_ele_cell(i)+1
cell_ele(i,num_ele_cell(i))=j
endif
enddo
enddo
!
!
allocate(distance(num_cells,num_elements))
! Find min distance between element centroid and cell faces/hyperplanes
do i=1,num_cells
if(i==1406) print *,num_faces(i)
do j=1,num_ele_cell(i)
centx=ele_centroid(cell_ele(i,j),1)
centy=ele_centroid(cell_ele(i,j),2)
centz=ele_centroid(cell_ele(i,j),3)
distmin=1000.
if(mask_type==5)then
do k=1,num_faces(i)
rnorx=face(i,k,1)
rnory=face(i,k,2)
rnorz=face(i,k,3)
roff=face(i,k,4)
dotprod=abs(centx*rnorx+centy*rnory+centz*rnorz+roff)
if(dotprod<distmin)distmin=dotprod
enddo
else
do k=1,num_faces(i)
x1=face(i,k,1)
x2=face(i,k,2)
y1=face(i,k,3)
y2=face(i,k,4)
dotprod=abs((x2-x1)*(y1-centy)-(x1-centx)*(y2-y1))
dotprod=dotprod/(sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)))
if(dotprod<distmin)distmin=dotprod
enddo
endif
distance(i,j)=distmin
enddo
enddo
!
! Write Element Sets
rewind(10)
open(unit=13,file='GeomGenINP.inp',status='unknown')
input2(1)='**'
do while (index(input2(1),'*End Part')==0)
read(10,'(a)')input2(2)
write(13,'(a)')input2(1)
input2(1)=input2(2)
enddo
do i=1,num_cells
if(num_ele_cell(i)==0)cycle
write(13,*)'*Elset,elset=ele',i
icheck=1
do j=1,num_ele_cell(i)
if(icheck==1)then
if(num_ele_cell(i)>1)then
write(13,'(i6)',advance='no')cell_ele(i,j)
else
write(13,'(i6)')cell_ele(i,j)
endif
elseif(icheck==num_ele_cell(i))then
write(13,'(a1,i6)')',',cell_ele(i,j)
else
if(mod(icheck,15)==0)then
write(13,'(a1,i6)')',',cell_ele(i,j)
else
write(13,'(a1,i6)',advance='no')',',cell_ele(i,j)
endif
endif
icheck=icheck+1
enddo
if(iana_type==1)write(19,*)'*Solid Section,elset=ele',i,'Boundary,material=Mat',i
enddo
write(13,*)'**'
do while (index(input2(1),'*End Assembly')==0)
read(10,'(a)')input2(2)
write(13,'(a)')input2(1)
input2(1)=input2(2)
enddo
write(13,'(a)')'*End Assembly'
write(13,*)'*INITIAL CONDITIONS,TYPE=SOLUTION'
do i=1,num_cells
if(num_ele_cell(i)==0)cycle
do j=1,num_ele_cell(i)
write(13,'(3(a,i6),2(a,f18.6),3(i6,a))')'Assembly.CorPart.',cell_ele(i,j),',' &
& ,cell_ele(i,j),',',max_neighbours,',',distance(i,j),',',cor_dist(cell_ele(i,j)) &
& ,0,',',0,',',0,','
write(13,'(8(i6,a))')0,',',0,',',0,',',0,',',0,',',0,',',0,',',1,','
do k=1, max_neighbours
if(mod(k,8)/=0)then
if(k/=max_neighbours)then
write(13,'(i6,a)',advance='no')neighbour(cell_ele(i,j),k),','
else
write(13,'(i6)')neighbour(cell_ele(i,j),k)
endif
else
if(k/=max_neighbours)then
write(13,'(i6,a)')neighbour(cell_ele(i,j),k),','
else
write(13,'(i6)')neighbour(cell_ele(i,j),k)
endif
endif
enddo
enddo
enddo
ierr=0
do while (ierr==0)
read(10,'(a)',iostat=ierr)input2(1)
if(ierr==0)write(13,'(a)')input2(1)
enddo
end program
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Generate Voronoi Tesselation Using QHULL
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine make_voronoi(mask_type,mesh_type,num_grains,num_x,rad_hard,grain_length)
integer mesh_type,mask_type,num_grains
integer seed(1)
double precision grain_length,rad_hard,rscale
if(mesh_type==2)mask_type=4
! Write QHull input file
open(unit=20,file='qhullin.dat',status='unknown')
write(20,*)mask_type-2
if(mask_type==5)write(20,*)num_grains*27
if(mask_type==4)write(20,*)num_grains*9
seed=1557
rscale=float(num_x)*Grain_Length
call random_seed(put=seed)
do i=1,num_grains
call random_number(xcor)
call random_number(ycor)
if(mask_type==5)call random_number(zcor)
xcor=xcor*rscale
ycor=ycor*rscale
if(mask_type==5)zcor=zcor*rscale
if(mask_type==4)then
write(20,*)xcor,ycor
write(20,*)xcor,ycor+rscale
write(20,*)xcor,ycor-rscale
write(20,*)xcor+rscale,ycor
write(20,*)xcor-rscale,ycor
write(20,*)xcor+rscale,ycor+rscale
write(20,*)xcor-rscale,ycor-rscale
write(20,*)xcor+rscale,ycor-rscale
write(20,*)xcor-rscale,ycor+rscale
elseif(mask_type==5)then
write(20,*)xcor,ycor,zcor
write(20,*)xcor+rscale,ycor,zcor
write(20,*)xcor-rscale,ycor,zcor
write(20,*)xcor,ycor+rscale,zcor
write(20,*)xcor,ycor-rscale,zcor
write(20,*)xcor+rscale,ycor+rscale,zcor
write(20,*)xcor-rscale,ycor-rscale,zcor
write(20,*)xcor+rscale,ycor-rscale,zcor
write(20,*)xcor-rscale,ycor+rscale,zcor
write(20,*)xcor,ycor,zcor+rscale
write(20,*)xcor+rscale,ycor,zcor+rscale
write(20,*)xcor-rscale,ycor,zcor+rscale
write(20,*)xcor,ycor+rscale,zcor+rscale
write(20,*)xcor,ycor-rscale,zcor+rscale
write(20,*)xcor+rscale,ycor+rscale,zcor+rscale
write(20,*)xcor-rscale,ycor-rscale,zcor+rscale
write(20,*)xcor+rscale,ycor-rscale,zcor+rscale
write(20,*)xcor-rscale,ycor+rscale,zcor+rscale
write(20,*)xcor,ycor,zcor-rscale
write(20,*)xcor+rscale,ycor,zcor-rscale
write(20,*)xcor-rscale,ycor,zcor-rscale
write(20,*)xcor,ycor+rscale,zcor-rscale
write(20,*)xcor,ycor-rscale,zcor-rscale
write(20,*)xcor+rscale,ycor+rscale,zcor-rscale
write(20,*)xcor-rscale,ycor-rscale,zcor-rscale
write(20,*)xcor+rscale,ycor-rscale,zcor-rscale
write(20,*)xcor-rscale,ycor+rscale,zcor-rscale
endif
enddo
close(20)
call system('qvoronoi.exe TI qhullin.dat o Fi TO qhullout.dat')
end subroutine
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Process Voronoi Tesselation - Return Arrays of Cell Faces and Centroids
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine process_voronoi(face_sub,num_faces_sub,cell_centroid,num_cells,cell_stat)
!
! Variables
character(len=320)full_line
character(len=320)test_string
character(len=256)input
character(len=256)input2(2)
integer seed (1)
integer cell_stat(20000)
integer,allocatable,dimension(:)::num_verts
integer,allocatable,dimension(:)::num_cell_hyp
integer,allocatable,dimension(:)::numverts
integer,dimension(20000)::num_faces_sub
integer,allocatable,dimension(:,:)::num_hyp_verts
integer,allocatable,dimension(:,:)::vert_list
integer,allocatable,dimension(:,:)::hyp_list
integer,allocatable,dimension(:,:)::facet
integer max_vc,max_hc,max_vh
double precision,allocatable,dimension(:)::xv_cor
double precision,allocatable,dimension(:)::yv_cor
double precision,allocatable,dimension(:)::zv_cor
double precision,allocatable,dimension(:)::offset
double precision,allocatable,dimension(:,:)::cor
double precision,allocatable,dimension(:,:)::ele_centroid
double precision,dimension(20000,3)::cell_centroid
double precision,dimension(20000,100,4)::face_sub
!
! Parameters
parameter(max_vc=100,max_hc=100,max_vh=50)
!
open(unit=21,file='qhullout.dat',status='unknown')
!
! Allocate Arrays
read(21,*)idimension
read(21,*)num_total_verts,num_cells
allocate(num_verts(num_cells))
allocate(xv_cor(num_total_verts),yv_cor(num_total_verts))
if(idimension==3)allocate(zv_cor(num_total_verts))
allocate(vert_list(num_cells,max_vc))
!
! Read in all vertice co-ordinates
do i=1,num_total_verts
if(idimension==2)read(21,*)xv_cor(i),yv_cor(i)
if(idimension==3)read(21,*)xv_cor(i),yv_cor(i),zv_cor(i)
enddo
!
! Read in vertice labels for each voronoi cell
do i=1,num_cells
read(21,*)num_verts(i)
backspace(21)
if(num_verts(i)>9)then
read(21,'(i3,a320)')idummy,full_line
else
read(21,'(i2,a320)')idummy,full_line
endif
ileft=1
num_points=1
do iright=1,320
test_string=full_line(iright:iright)
if((test_string==' ').or.(iright==320))then
read(full_line(ileft:iright-1),'(i6)')vert_list(i,num_points)
if(num_points==num_verts(i))exit
ileft=iright+1
num_points=num_points+1
endif
enddo
do j=1,num_points-1
if(vert_list(i,j)==0)cell_stat(i)=1
enddo
enddo
if(idimension==3)then
!
! Read in bounded hyperplane cell labels and co-ordinates
read(21,*)num_hyp
allocate(facet(2,num_hyp),cor(3,num_hyp),offset(num_hyp))
allocate(hyp_list(num_cells,num_hyp),num_cell_hyp(num_cells))
!
do i=1,num_hyp
read(21,*)dummy,facet(1,i),facet(2,i),cor(1,i),cor(2,i),cor(3,i),offset(i)
enddo
!
! Determine hyperplanes of each cell
do i=1,num_cells
num_hy=1
do j=1,num_hyp
if((facet(1,j)==i-1).or.(facet(2,j)==i-1))then
hyp_list(i,num_hy)=j
num_cell_hyp(i)=num_hy
num_hy=num_hy+1
endif
enddo
enddo
!
! Store hyperplane info in convenient format
do i=1,num_cells
num_faces_sub(i)=num_cell_hyp(i)
do j=1,num_cell_hyp(i)
face_sub(i,j,1)=cor(1,hyp_list(i,j))
face_sub(i,j,2)=cor(2,hyp_list(i,j))
face_sub(i,j,3)=cor(3,hyp_list(i,j))
face_sub(i,j,4)=offset(hyp_list(i,j))
enddo
enddo
else
do i=1,num_cells
num_faces_sub(i)=num_verts(i)
do j=1,num_verts(i)
x2=xv_cor(vert_list(i,j)+1)
y2=yv_cor(vert_list(i,j)+1)
if(j==1)then
x1=xv_cor(vert_list(i,num_verts(i))+1)
y1=yv_cor(vert_list(i,num_verts(i))+1)
else
x1=xv_cor(vert_list(i,j-1)+1)
y1=yv_cor(vert_list(i,j-1)+1)
endif
face_sub(i,j,1)=x1
face_sub(i,j,2)=x2
face_sub(i,j,3)=y1
face_sub(i,j,4)=y2
enddo
enddo
endif
!
! Get cell centroid
do i=1,num_cells
centroidx=0.
centroidy=0.
centroidz=0.
do j=1,num_verts(i)
centroidx=centroidx+xv_cor(vert_list(i,j)+1)
centroidy=centroidy+yv_cor(vert_list(i,j)+1)
if(idimension==3)centroidz=centroidz+zv_cor(vert_list(i,j)+1)
enddo
cell_centroid(i,1)=centroidx/float(num_verts(i))
cell_centroid(i,2)=centroidy/float(num_verts(i))
if(idimension==3)then
cell_centroid(i,3)=centroidz/float(num_verts(i))
else
cell_centroid(i,3)=0.d0
endif
enddo
if(idimension==3)then
! Flip hyperplane normal if it points away from cell centroid
do i=1,num_cells
centx=cell_centroid(i,1)
centy=cell_centroid(i,2)
centz=cell_centroid(i,3)
distmin=1000.
do k=1,num_faces_sub(i)
rnorx=face_sub(i,k,1)
rnory=face_sub(i,k,2)
rnorz=face_sub(i,k,3)
roff=face_sub(i,k,4)
dotprod=centx*rnorx+centy*rnory+centz*rnorz+roff
if(dotprod<0.)then
face_sub(i,k,1)=-face_sub(i,k,1)
face_sub(i,k,2)=-face_sub(i,k,2)
face_sub(i,k,3)=-face_sub(i,k,3)
face_sub(i,k,4)=-face_sub(i,k,4)
endif
enddo
enddo
endif
close(unit=21)
deallocate(num_verts,xv_cor,yv_cor)
if(idimension==3)deallocate(zv_cor,facet,cor,offset,hyp_list,num_cell_hyp)
end subroutine
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Make Squares - Return Arrays of Cell Faces and Centroids
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine make_square(i,j,k,grain_length,num_faces,face,cell_centroid,mesh_type)
!
integer num_faces,m
double precision grain_length,centrex,centrey,centrez,rsign,xnor,ynor,znor
double precision rdist
double precision,dimension(3)::cell_centroid
double precision,dimension(6,4)::face
!
!
num_faces=4
centrex=(i-1)*Grain_length+Grain_length/2.d0
centrey=(j-1)*Grain_length+Grain_length/2.d0
if(mesh_type==3)then
centrez=(k-1)*Grain_length+Grain_length/2.d0
else
centrez=0.d0
endif
!
! Centroid
cell_centroid(1)=centrex
cell_centroid(2)=centrey
cell_centroid(3)=centrez
!
! Faces
do m=1,num_faces
rsign=1.d0
xnor=0.d0
ynor=0.d0
znor=0.d0
unitx=grain_length/2.d0
unity=grain_length/2.d0
if(mod(m,2)==0)rsign=-1.d0
if(m<=2)then
x1=centrex+rsign*unitx
x2=centrex+rsign*unitx
y1=centrey+unity
y2=centrey-unity
else
x1=centrex+unitx
x2=centrex-unitx
y1=centrey+rsign*unity
y2=centrey+rsign*unity
endif
face(m,1)=x1
face(m,2)=x2
face(m,3)=y1
face(m,4)=y2
enddo
end Subroutine
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Make Hexagons - Return Arrays of Cell Faces and Centroids
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine make_hexagon(i,j,k,grain_length,num_faces,face,cell_centroid,mesh_type)
integer num_faces,m
double precision grain_length,centrex,centrey,centrez,rsign,xnor,ynor,znor
double precision rdist
double precision,dimension(3)::cell_centroid
double precision,dimension(6,4)::face
!
!
num_faces=6
if(mod(j,2)==0)then
centrex=(i-1)*sqrt(3.d0)*Grain_length+sqrt(3.d0)*Grain_length/2.d0
else
centrex=(i-1)*sqrt(3.)*Grain_length
endif
centrey=(j-1)*1.5d0*Grain_length
if(mesh_type==3)then
centrez=(k-1)*Grain_length
else
centrez=0.d0
endif
!
! Centroid
cell_centroid(1)=centrex
cell_centroid(2)=centrey
cell_centroid(3)=centrez
!
! Faces
do m=1,num_faces
rsign=1.d0
rsign2=1.d0
xnor=0.d0
ynor=0.d0
znor=0.d0
unity=0.5d0*grain_length
unitx=(sqrt(3.d0)/2.d0)*grain_length
if(mod(m,2)==0)rsign=-1.d0
if(m<=2)then
x1=centrex+rsign*unitx
x2=centrex+rsign*unitx
y1=centrey+unity
y2=centrey-unity
elseif(m>2.and.m<=4)then
x1=centrex
x2=centrex+unitx
y1=centrey+rsign*unity*2.d0
y2=centrey+rsign*unity
else
x1=centrex
x2=centrex-unitx
y1=centrey+rsign*unity*2.d0
y2=centrey+rsign*unity
endif
face(m,1)=x1
face(m,2)=x2
face(m,3)=y1
face(m,4)=y2
enddo
end Subroutine
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Get Element Centroids
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine elem_centroids(ne,ele_centroid,mesh_type)
!
! Parameters
parameter(max_nodes=1000000,max_elements=100000,max_node_in_elem=8)
!
! Variables
character(len=256)input
integer,dimension(max_elements,max_node_in_elem)::elements
double precision,dimension(max_nodes,3)::nodes
double precision,dimension(max_elements,3)::ele_centroid
!
! Open Input File and read node and element co-ordinates
open(unit=10,file='GeomGenTemp.inp',status='unknown')
do while (index(input,'*Node')==0)
read(10,'(a)')input
end do
nn=0
do while(1==1)
read(10,'(a)')input
if(index(input,'*')==0)then
backspace(10)
nn=nn+1
if(mesh_type==3)then
read(10,*)dummy,nodes(nn,1),nodes(nn,2),nodes(nn,3)
else
read(10,*)dummy,nodes(nn,1),nodes(nn,2)
endif
else
if(mesh_type==2)then
nele_type=4
else
if(index(input,'C3D8')/=0)nele_type=8
if(index(input,'C3D4')/=0)nele_type=4
endif
exit
endif
end do
ne=0
do while(1==1)
read(10,'(a)')input
if(index(input,'*')==0)then
backspace(10)
ne=ne+1
if(nele_type==8)then
read(10,*)dummy,elements(ne,1),elements(ne,2),elements(ne,3),elements(ne,4)&
& ,elements(ne,5),elements(ne,6),elements(ne,7),elements(ne,8)
elseif(nele_type==4)then
read(10,*)dummy,elements(ne,1),elements(ne,2),elements(ne,3),elements(ne,4)
endif
else
exit
endif
end do
!
! Get element centroid
do i=1,ne
centroidx=0.d0
centroidy=0.d0
centroidz=0.d0
do j=1,nele_type
centroidx=centroidx+nodes(elements(i,j),1)
centroidy=centroidy+nodes(elements(i,j),2)
if(mesh_type==3)centroidz=centroidz+nodes(elements(i,j),3)
enddo
ele_centroid(i,1)=centroidx/float(nele_type)
ele_centroid(i,2)=centroidy/float(nele_type)
if(mesh_type==3)ele_centroid(i,3)=centroidz/float(nele_type)
enddo
end subroutine

View file

@ -0,0 +1,205 @@
! This program generates a micro-strucutre mask and applies it to
! an existing mesh.
! J.Grogan 05/08/11
program Corrosion_Preprocessor
!
! Parameters
parameter(max_elements=600000,max_cells=20000,max_fc=100,max_faces=10000)
parameter(max_elem_in_cell=50000,max_neigh_per_elem=6,max_neighbours=50)
!
! Variables
character(len=256)input
character(len=256)input2(2)
integer,allocatable,dimension(:)::num_faces
integer,dimension(max_elements,max_neighbours)::neighbour
integer mesh_type
integer(1) iseed
double precision,allocatable,dimension(:,:)::distance
double precision,allocatable,dimension(:,:)::nbr_dist
double precision,allocatable,dimension(:,:)::cor_faces
double precision,dimension(max_elements)::cor_dist
double precision,allocatable,dimension(:,:)::ele_centroid
!
! Mesh Type: 2 = 2D, 3 = 3D
mesh_type=3
iseed=3
call random_seed(iseed)
!
allocate(ele_centroid(max_elements,3))
! Get element centroids
call elem_centroids(num_elements,ele_centroid,mesh_type)
!
! Get neighbouring elements
allocate(nbr_dist(max_elements,max_neighbours))
do i=1,num_elements
icount=1
do j=1,num_elements
if(icount>max_neighbours)then
rmaxdist=0.
do k=1,max_neighbours
if(nbr_dist(i,k)>rmaxdist)then
rmaxdist=nbr_dist(i,k)
index_max_dist=k
endif
enddo
endif
cent1x=ele_centroid(i,1)
cent1y=ele_centroid(i,2)
cent1z=ele_centroid(i,3)
cent2x=ele_centroid(j,1)
cent2y=ele_centroid(j,2)
cent2z=ele_centroid(j,3)
dist=sqrt((cent1x-cent2x)*(cent1x-cent2x)+(cent1y-cent2y)*(cent1y-cent2y)&
&+(cent1z-cent2z)*(cent1z-cent2z))
if(icount>max_neighbours)then
if(dist<rmaxdist)then
nbr_dist(i,index_max_dist)=dist
neighbour(i,index_max_dist)=j
endif
else
nbr_dist(i,j)=dist
neighbour(i,j)=j
endif
icount=icount+1
enddo
print *,float(i)/float(num_elements)
enddo
deallocate(nbr_dist)
!
! Get corrosion surface distances
open(unit=22,file='CorSurf.dat',status='unknown')
allocate(cor_faces(max_faces,3))
ierr=0
inum_faces=1
do while (ierr==0)
read(22,*,iostat=ierr)cor_faces(inum_faces,1),cor_faces(inum_faces,2),&
&cor_faces(inum_faces,3)
if(ierr==0)inum_faces=inum_faces+1
enddo
close(unit=22)
do i=1,num_elements
centx=ele_centroid(i,1)
centy=ele_centroid(i,2)
centz=ele_centroid(i,3)
distmin=1000.
do j=1,inum_faces-1
facex=cor_faces(j,1)
facey=cor_faces(j,2)
facez=cor_faces(j,3)
dist=sqrt((centx-facex)*(centx-facex)+(centy-facey)*(centy-facey)&
&+(centz-facez)*(centz-facez))
if(dist<distmin)distmin=dist
enddo
cor_dist(i)=distmin
enddo
deallocate(cor_faces)
!
rewind(10)
open(unit=13,file='GeomGenINP.inp',status='unknown')
input2(1)='**'
do while (index(input2(1),'*End Assembly')==0)
read(10,'(a)')input2(2)
write(13,'(a)')input2(1)
input2(1)=input2(2)
enddo
write(13,'(a)')'*End Assembly'
write(13,*)'*INITIAL CONDITIONS,TYPE=SOLUTION'
do i=1,num_elements
call random_number(randnum)
randnum=0
write(13,'(3(a,i6),2(a,f18.6),a,2(i6,a),f18.6,a)')'Assembly.CorPart.',i,',' &
& ,i,',',max_neighbours,',',0.,',',cor_dist(i),',',0,',',1,',',randnum,','
do k=1, max_neighbours
if(mod(k,8)/=0)then
if(k/=max_neighbours)then
write(13,'(i6,a)',advance='no')neighbour(i,k),','
else
write(13,'(i6,a,f18.6,a,i6,a,i6,a,i6)')neighbour(i,k),',',cor_dist(i),',',0,',',0,',',0
endif
else
if(k/=max_neighbours)then
write(13,'(i6,a)')neighbour(i,k),','
else
write(13,'(i6,a,f18.6,a,i6,a,i6,a,i6)')neighbour(i,k),',',cor_dist(i),',',0,',',0,',',0
endif
endif
enddo
enddo
ierr=0
do while (ierr==0)
read(10,'(a)',iostat=ierr)input2(1)
if(ierr==0)write(13,'(a)')input2(1)
enddo
end program
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Get Element Centroids
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
subroutine elem_centroids(ne,ele_centroid,mesh_type)
!
! Parameters
parameter(max_nodes=6000000,max_elements=600000,max_node_in_elem=8)
!
! Variables
character(len=256)input
integer,dimension(max_elements,max_node_in_elem)::elements
double precision,dimension(max_nodes,3)::nodes
double precision,dimension(max_elements,3)::ele_centroid
!
! Open Input File and read node and element co-ordinates
open(unit=10,file='GeomGenTemp.inp',status='unknown')
do while (index(input,'*Node')==0)
read(10,'(a)')input
end do
nn=0
do while(1==1)
read(10,'(a)')input
if(index(input,'*')==0)then
backspace(10)
nn=nn+1
if(mesh_type==3)then
read(10,*)dummy,nodes(nn,1),nodes(nn,2),nodes(nn,3)
else
read(10,*)dummy,nodes(nn,1),nodes(nn,2)
endif
else
if(mesh_type==2)then
nele_type=4
else
if(index(input,'C3D8')/=0)nele_type=8
if(index(input,'C3D4')/=0)nele_type=4
endif
exit
endif
end do
ne=0
do while(1==1)
read(10,'(a)')input
if(index(input,'*')==0)then
backspace(10)
ne=ne+1
if(nele_type==8)then
read(10,*)dummy,elements(ne,1),elements(ne,2),elements(ne,3),elements(ne,4)&
& ,elements(ne,5),elements(ne,6),elements(ne,7),elements(ne,8)
elseif(nele_type==4)then
read(10,*)dummy,elements(ne,1),elements(ne,2),elements(ne,3),elements(ne,4)
endif
else
exit
endif
end do
!
! Get element centroid
do i=1,ne
centroidx=0.d0
centroidy=0.d0
centroidz=0.d0
do j=1,nele_type
centroidx=centroidx+nodes(elements(i,j),1)
centroidy=centroidy+nodes(elements(i,j),2)
if(mesh_type==3)centroidz=centroidz+nodes(elements(i,j),3)
enddo
ele_centroid(i,1)=centroidx/float(nele_type)
ele_centroid(i,2)=centroidy/float(nele_type)
if(mesh_type==3)ele_centroid(i,3)=centroidz/float(nele_type)
enddo
end subroutine

View file

@ -0,0 +1,88 @@
! This program takes output from the QHULL package and converts it into
! a format suitable for use with the GeomGen script
! J.Grogan 05/08/11
program Voronoi2DPost
!
! Parameters
parameter(max_verts=1000000,max_cells=100000,max_verts_in_cell=100)
!
! Variables
character(len=256)full_line,test_string
integer vnum(max_cells,max_verts_in_cell),num_verts(max_cells)
integer in_tol(max_cells)
real xv_cor(max_verts)
real yv_cor(max_verts)
logical xtrue
logical ytrue
!
! Read Scales
open(unit=15,file='scales.dat',status='unknown')
read(15,*)rmaxscale
!
! Read in vertex co-ordinates
open(unit=11,file='qhullout.dat',status='unknown')
read(11,*)
read(11,*)num_verts_tot,num_cells,dummy
do i=1,num_verts_tot
read(11,*)xv_cor(i),yv_cor(i)
enddo
!
! Read in vertices on each cell
do i=1,num_cells
read(11,*)num_verts(i)
backspace(11)
read(11,'(i2,a256)')idummy,full_line
ileft=1
num_points=1
do iright=1,256
test_string=full_line(iright:iright)
if((test_string==' ').or.(iright==256))then
read(full_line(ileft:iright-1),'(i6)')vnum(i,num_points)
if(num_points==num_verts(i))exit
ileft=iright+1
num_points=num_points+1
endif
enddo
enddo
!
! Check if cells are within specified region
open(unit=12,file='fortranout.dat',status='unknown')
num_inside_cells=num_cells
do i=1,num_cells
icheck=0
do j=1,num_verts(i)
xcor=xv_cor(vnum(i,j)+1)
ycor=yv_cor(vnum(i,j)+1)
if(abs(xcor)==10.101)then
icheck=0
exit
endif
rmax=1.1*rmaxscale
rmin=-0.1
xtrue=(xcor<rmax).and.(xcor>rmin)
ytrue=(ycor<rmax).and.(ycor>rmin)
if(xtrue.and.ytrue)icheck=icheck+1
enddo
if(icheck<1)then
in_tol(i)=2
num_inside_cells=num_inside_cells-1
else
in_tol(i)=1
endif
enddo
!
! Write vertex coordinates for each cell
write(12,*)num_inside_cells
do i=1,num_cells
if(in_tol(i)==1)then
write(12,*)num_verts(i)
do j=1,num_verts(i)
write(12,*)xv_cor(vnum(i,j)+1),',',yv_cor(vnum(i,j)+1)
enddo
else
cycle
endif
enddo
close(unit=11)
close(unit=12)
end program

View file

@ -0,0 +1,141 @@
! This program takes output from the QHULL package and converts it into
! a format suitable for use with the GeomGen script
! J.Grogan 05/08/11
program Voronoi3DPost
!
! Parameters
parameter(max_verts=500000,max_cells=50000,max_verts_in_cell=100)
parameter(max_hyps=500000,max_hyp_in_cell=100,max_verts_on_hyp=50)
!
! Variables
character(len=256)full_line,test_string
integer num_verts(max_cells)
integer vert_list(max_cells,max_verts_in_cell)
integer facet(2,max_hyps)
integer hyp_list(max_cells,max_hyp_in_cell)
integer num_cell_hyp(max_cells)
integer cell_status(max_cells)
integer num_hyp_verts(max_cells,max_hyp_in_cell)
integer hyp_vert_list(max_cells,max_hyp_in_cell,max_verts_on_hyp)
double precision xv_cor(max_verts)
double precision yv_cor(max_verts)
double precision zv_cor(max_verts)
double precision cor(3,max_hyps)
double precision offset(max_hyps)
double precision xcor,ycor,zcor
double precision dotrprod,distance,tol
logical xtrue,ytrue,ztrue
!
! Open output files
open(unit=12,file='fortranout.dat',status='unknown')
!
! Open scales file
open(unit=15,file='scales.dat',status='unknown')
read(15,*)rmaxscale
!
! Read tessellation results from QHULL
open(unit=11,file='qhullout.dat',status='unknown')
read(11,*)
read(11,*)num_total_verts,num_cells
!
! Read in all vertice co-ordinates
do i=1,num_total_verts
read(11,*)xv_cor(i),yv_cor(i),zv_cor(i)
enddo
!
! Read in vertice labels for each voronoi cell
do i=1,num_cells
read(11,*)num_verts(i)
backspace(11)
if(num_verts(i)>9)then
read(11,'(i3,a256)')idummy,full_line
else
read(11,'(i2,a256)')idummy,full_line
endif
ileft=1
num_points=1
do iright=1,256
test_string=full_line(iright:iright)
if((test_string==' ').or.(iright==256))then
read(full_line(ileft:iright-1),'(i6)')vert_list(i,num_points)
if(num_points==num_verts(i))exit
ileft=iright+1
num_points=num_points+1
endif
enddo
enddo
!
! Read in bounded hyperplane cell labels and co-ordinates
read(11,*)num_hyp
do i=1,num_hyp
read(11,*)dummy,facet(1,i),facet(2,i),cor(1,i),cor(2,i),cor(3,i),offset(i)
enddo
!
! Determine hyperplanes of each cell
do i=1,num_cells
num_hy=1
do j=1,num_hyp
if((facet(1,j)==i-1).or.(facet(2,j)==i-1))then
hyp_list(i,num_hy)=j
num_cell_hyp(i)=num_hy
num_hy=num_hy+1
endif
enddo
enddo
!
! Check if any cell vertices are outside the chosen tolerance
do i=1,num_cells
cell_status(i)=1
do j=1,num_verts(i)
xcor=xv_cor(vert_list(i,j)+1)
ycor=yv_cor(vert_list(i,j)+1)
zcor=zv_cor(vert_list(i,j)+1)
rmax=1.1*rmaxscale
rmin=-0.1
xtrue=(xcor<rmax).and.(xcor>rmin)
ytrue=(ycor<rmax).and.(ycor>rmin)
ztrue=(zcor<rmax).and.(zcor>rmin)
if(xtrue.and.ytrue.and.ztrue)cell_status(i)=0
enddo
enddo
!
! For all cells within tolerance determine vertices on each hyperplane
num_skipped=0
tol=1.e-5*rmaxscale
do i=1,num_cells
if(cell_status(i)/=0)then
num_skipped=num_skipped+1
cycle
endif
do j=1,num_cell_hyp(i)
nverts_on_hyp=1
do k=1,num_verts(i)
dotprod1=cor(1,hyp_list(i,j))*xv_cor(vert_list(i,k)+1)
dotprod2=cor(2,hyp_list(i,j))*yv_cor(vert_list(i,k)+1)
dotprod3=cor(3,hyp_list(i,j))*zv_cor(vert_list(i,k)+1)
distance=dotprod1+dotprod2+dotprod3+offset(hyp_list(i,j))
if(abs(distance)<tol)then
hyp_vert_list(i,j,nverts_on_hyp)=vert_list(i,k)
num_hyp_verts(i,j)=nverts_on_hyp
nverts_on_hyp=nverts_on_hyp+1
endif
enddo
enddo
enddo
! Write output for the of co-orindates of vertices on each hyperplane
! that make up a cell.
write(12,*)num_cells-num_skipped
do i=1,num_cells
if(cell_status(i)/=0)cycle
write(12,*)num_cell_hyp(i)
do j=1,num_cell_hyp(i)
write(12,*)num_hyp_verts(i,j)
do k=1,num_hyp_verts(i,j)
xcor=xv_cor(hyp_vert_list(i,j,k)+1)
ycor=yv_cor(hyp_vert_list(i,j,k)+1)
zcor=zv_cor(hyp_vert_list(i,j,k)+1)
write(12,'(2(f20.15,a),f20.15)')xcor,',',ycor,',',zcor
enddo
enddo
enddo
end program

View file

@ -0,0 +1,215 @@
# 3D PCBs - JGrogan - V1.0
# V1.0 - Ceated: 18-02-12
from abaqus import *
from abaqusConstants import *
#
zModel=mdb.models['Model-1']
zAssembly=zModel.rootAssembly
zInstance=zAssembly.instances['Part-1-1']
#
# Enter Node Selection Tolerance and a 'Big' Number
Toler=1.e-6
BigNum=1.e6
# Characterize Part
XMax=-BigNum
YMax=-BigNum
ZMax=-BigNum
XMin=BigNum
YMin=BigNum
ZMin=BigNum
for eachNode in zInstance.nodes:
XCor=eachNode.coordinates[0]
YCor=eachNode.coordinates[1]
ZCor=eachNode.coordinates[2]
if XCor>XMax:
XMax=XCor
elif XCor<XMin:
XMin=XCor
if YCor>YMax:
YMax=YCor
elif YCor<YMin:
YMin=YCor
if ZCor>ZMax:
ZMax=ZCor
elif ZCor<ZMin:
ZMin=ZCor
#
# Distribute Nodes into Sets
for eachNode in zInstance.nodes:
XCor=eachNode.coordinates[0]
YCor=eachNode.coordinates[1]
ZCor=eachNode.coordinates[2]
# Front Face, Edges and Nodes
if(XCor<XMax+Toler)and(XCor>XMax-Toler):
if(YCor<YMax+Toler)and(YCor>YMax-Toler):
if(ZCor<ZMax+Toler)and(ZCor>ZMax-Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='B',nodes=Node)
elif(ZCor<ZMin+Toler)and(ZCor>ZMin-Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='C',nodes=Node)
else:
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='EdgeBC', sets=(zAssembly.sets['EdgeBC'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='EdgeBC',nodes=Node)
elif(YCor<YMin+Toler)and(YCor>YMin-Toler):
if(ZCor<ZMax+Toler)and(ZCor>ZMax-Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='B1',nodes=Node)
elif(ZCor<ZMin+Toler)and(ZCor>ZMin-Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='C1',nodes=Node)
else:
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='EdgeB1C1', sets=(zAssembly.sets['EdgeB1C1'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='EdgeB1C1',nodes=Node)
elif(ZCor<ZMax+Toler)and(ZCor>ZMax-Toler):
if(YCor<YMax-Toler)and(YCor>YMin+Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='EdgeBB1', sets=(zAssembly.sets['EdgeBB1'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='EdgeBB1',nodes=Node)
elif(ZCor<ZMin+Toler)and(ZCor>ZMin-Toler):
if(YCor<YMax-Toler)and(YCor>YMin+Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='EdgeCC1', sets=(zAssembly.sets['EdgeCC1'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='EdgeCC1',nodes=Node)
else:
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='FaceFront', sets=(zAssembly.sets['FaceFront'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='FaceFront',nodes=Node)
# Back Face, Edges and Nodes
elif(XCor<XMin+Toler)and(XCor>XMin-Toler):
if(YCor<YMax+Toler)and(YCor>YMax-Toler):
if(ZCor<ZMax+Toler)and(ZCor>ZMax-Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='A',nodes=Node)
elif(ZCor<ZMin+Toler)and(ZCor>ZMin-Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='D',nodes=Node)
else:
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='EdgeAD', sets=(zAssembly.sets['EdgeAD'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='EdgeAD',nodes=Node)
elif(YCor<YMin+Toler)and(YCor>YMin-Toler):
if(ZCor<ZMax+Toler)and(ZCor>ZMax-Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='A1',nodes=Node)
elif(ZCor<ZMin+Toler)and(ZCor>ZMin-Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='D1',nodes=Node)
else:
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='EdgeA1D1', sets=(zAssembly.sets['EdgeA1D1'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='EdgeA1D1',nodes=Node)
elif(ZCor<ZMax+Toler)and(ZCor>ZMax-Toler):
if(YCor<YMax-Toler)and(YCor>YMin+Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='EdgeAA1', sets=(zAssembly.sets['EdgeAA1'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='EdgeAA1',nodes=Node)
elif(ZCor<ZMin+Toler)and(ZCor>ZMin-Toler):
if(YCor<YMax-Toler)and(YCor>YMin+Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='EdgeDD1', sets=(zAssembly.sets['EdgeDD1'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='EdgeDD1',nodes=Node)
else:
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='FaceRear', sets=(zAssembly.sets['FaceRear'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='FaceRear',nodes=Node)
# Top Face and Edges
elif(YCor<YMax+Toler)and(YCor>YMax-Toler):
if(XCor<XMax-Toler)and(XCor>XMin+Toler):
if(ZCor<ZMax+Toler)and(ZCor>ZMax-Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='EdgeAB', sets=(zAssembly.sets['EdgeAB'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='EdgeAB',nodes=Node)
elif(ZCor<ZMin+Toler)and(ZCor>ZMin-Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='EdgeCD', sets=(zAssembly.sets['EdgeCD'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='EdgeCD',nodes=Node)
else:
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='FaceTop', sets=(zAssembly.sets['FaceTop'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='FaceTop',nodes=Node)
# Bottom Face and Edges
elif(YCor<YMin+Toler)and(YCor>YMin-Toler):
if(XCor<XMax-Toler)and(XCor>XMin+Toler):
if(ZCor<ZMax+Toler)and(ZCor>ZMax-Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='EdgeA1B1', sets=(zAssembly.sets['EdgeA1B1'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='EdgeA1B1',nodes=Node)
elif(ZCor<ZMin+Toler)and(ZCor>ZMin-Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='EdgeC1D1', sets=(zAssembly.sets['EdgeC1D1'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='EdgeC1D1',nodes=Node)
else:
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='FaceBottom', sets=(zAssembly.sets['FaceBottom'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='FaceBottom',nodes=Node)
# Left Face
elif(ZCor<ZMax+Toler)and(ZCor>ZMax-Toler):
if(XCor<XMax-Toler)and(XCor>XMin+Toler)and(YCor>YMin+Toler)and(YCor>YMin+Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='FaceLeft', sets=(zAssembly.sets['FaceLeft'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='FaceLeft',nodes=Node)
elif(ZCor<ZMin+Toler)and(ZCor>ZMin-Toler):
if(XCor<XMax-Toler)and(XCor>XMin+Toler)and(YCor>YMin+Toler)and(YCor>YMin+Toler):
Node=zInstance.nodes.sequenceFromLabels(labels=(eachNode.label,))
zAssembly.Set(name='Temp',nodes=Node)
try:
zAssembly.SetByMerge(name='FaceRight', sets=(zAssembly.sets['FaceRight'],zAssembly.sets['Temp']))
except:
zAssembly.Set(name='FaceRight',nodes=Node)
# Clean Up
del zAssembly.sets['Temp']

View file

@ -0,0 +1,261 @@
# 3D PCBs - JGrogan - V1.0
# V1.0 - Ceated: 18-02-12
from abaqus import *
from abaqusConstants import *
#
# Define Tolerance for Node Matching:
Toler = 0.0001
#
zModel=mdb.models['Model-1']
zAssembly=zModel.rootAssembly
#
# Constraints
for j in range(0,3):
if j == 0:
Name1='FaceBottom'
Name2='FaceTop'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=-1.
Coeff31=1. #
Coeff32=-1.
Coeff33=0.
elif j == 1:
Name1='FaceFront'
Name2='FaceRear'
Coeff11=1.
Coeff12=-1.
Coeff13=-1.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=0.
elif j == 2:
Name1='FaceLeft'
Name2='FaceRight'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=-1.
elif j == 3:
Name1='EdgeCC1'
Name2='EdgeBB1'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=1.
elif j == 4:
Name1='EdgeBB1'
Name2='EdgeAA1'
Coeff11=1.
Coeff12=-1.
Coeff13=-1.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=0.
elif j == 5:
Name1='EdgeAA1'
Name2='EdgeDD1'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=-1.
elif j == 6:
Name1='EdgeCD'
Name2='EdgeAB'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=1.
elif j == 6:
Name1='EdgeAB'
Name2='EdgeA1B1'
Coeff11=-1.
Coeff12=1.
Coeff13=0.
Coeff21=-1. #
Coeff22=1.
Coeff23=-1.
Coeff31=-1. #
Coeff32=-1.
Coeff33=0.
elif j == 7:
Name1='EdgeA1B1'
Name2='EdgeC1D1'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=-1.
elif j == 7:
Name1='EdgeAD'
Name2='EdgeBC'
Coeff11=-1.
Coeff12=1.
Coeff13=-1.
Coeff21=-1. #
Coeff22=1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=0.
elif j == 8:
Name1='EdgeBC'
Name2='EdgeB1C1'
Coeff11=-1.
Coeff12=1.
Coeff13=0.
Coeff21=-1. #
Coeff22=1.
Coeff23=-1.
Coeff31=1. #
Coeff32=-1.
Coeff33=0.
elif j == 8:
Name1='EdgeB1C1'
Name2='EdgeA1D1'
Coeff11=1.
Coeff12=-1.
Coeff13=-1.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=0.
elif j == 9:
Name1='B'
Name2='C'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=-1.
elif j == 10:
Name1='A'
Name2='D'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=-1. #
Coeff22=1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=-1.
elif j == 11:
Name1='C'
Name2='C1'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=1.
Coeff31=1. #
Coeff32=-1.
Coeff33=-0.
elif j == 12:
Name1='D'
Name2='D1'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=1.
Coeff31=1. #
Coeff32=-1.
Coeff33=-0.
elif j == 13:
Name1='C1'
Name2='B1'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=1.
elif j == 14:
Name1='D1'
Name2='A1'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=1.
elif j == 15:
Name1='A1'
Name2='B1'
Coeff11=-1.
Coeff12=1.
Coeff13=-1.
Coeff21=-1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=0.
i=1
entity1=zAssembly.sets[Name1].nodes
entity2=zAssembly.sets[Name2].nodes
for eachNode1 in entity1:
cor1x=eachNode1.coordinates[0]
cor1y=eachNode1.coordinates[1]
cor1z=eachNode1.coordinates[2]
for eachNode2 in entity2:
distx=abs(cor1x-eachNode2.coordinates[0])
disty=abs(cor1y-eachNode2.coordinates[1])
distz=abs(cor1z-eachNode2.coordinates[2])
if (distx<Toler and disty<Toler)or(disty<Toler and distz<Toler)or(distx<Toler and distz<Toler) :
Node1=entity1.sequenceFromLabels(labels=(eachNode1.label,))
Node2=entity2.sequenceFromLabels(labels=(eachNode2.label,))
ZAssembly.Set(name=Name1+str(i),nodes=Node1)
ZAssembly.Set(name=Name2+str(i),nodes=Node2)
ZModel.Equation(name=Name1+Name2+'1'+str(i),terms=((Coeff11,Name1+str(i),1),(Coeff12,Name2+str(i),1),(Coeff13,'Dummy',1)))
ZModel.Equation(name=Name1+Name2+'2'+str(i),terms=((Coeff21,Name1+str(i),2),(Coeff22,Name2+str(i),2),(Coeff23,'Dummy',2)))
ZModel.Equation(name=Name1+Name2+'3'+str(i),terms=((Coeff31,Name1+str(i),3),(Coeff32,Name2+str(i),3),(Coeff33,'Dummy',3)))
i=i+1

View file

@ -0,0 +1,261 @@
# 3D PCBs - JGrogan - V1.0
# V1.0 - Ceated: 18-02-12
from abaqus import *
from abaqusConstants import *
#
# Define Tolerance for Node Matching:
Toler = 0.0001
#
zModel=mdb.models['Model-1']
zAssembly=zModel.rootAssembly
#
# Constraints
for j in range(0,19):
if j == 0:
Name1='FaceBottom'
Name2='FaceTop'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=-1.
Coeff31=1. #
Coeff32=-1.
Coeff33=0.
elif j == 1:
Name1='FaceFront'
Name2='FaceRear'
Coeff11=1.
Coeff12=-1.
Coeff13=-1.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=0.
elif j == 2:
Name1='FaceLeft'
Name2='FaceRight'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=-1.
elif j == 3:
Name1='EdgeCC1'
Name2='EdgeBB1'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=1.
elif j == 4:
Name1='EdgeBB1'
Name2='EdgeAA1'
Coeff11=1.
Coeff12=-1.
Coeff13=-1.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=0.
elif j == 5:
Name1='EdgeAA1'
Name2='EdgeDD1'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=-1.
elif j == 6:
Name1='EdgeCD'
Name2='EdgeAB'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=1.
elif j == 7:
Name1='EdgeAB'
Name2='EdgeA1B1'
Coeff11=-1.
Coeff12=1.
Coeff13=0.
Coeff21=-1. #
Coeff22=1.
Coeff23=-1.
Coeff31=-1. #
Coeff32=1.
Coeff33=0.
elif j == 8:
Name1='EdgeA1B1'
Name2='EdgeC1D1'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=-1.
elif j == 9:
Name1='EdgeAD'
Name2='EdgeBC'
Coeff11=-1.
Coeff12=1.
Coeff13=-1.
Coeff21=-1. #
Coeff22=1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=0.
elif j == 10:
Name1='EdgeBC'
Name2='EdgeB1C1'
Coeff11=-1.
Coeff12=1.
Coeff13=0.
Coeff21=-1. #
Coeff22=1.
Coeff23=-1.
Coeff31=1. #
Coeff32=-1.
Coeff33=0.
elif j == 11:
Name1='EdgeB1C1'
Name2='EdgeA1D1'
Coeff11=1.
Coeff12=-1.
Coeff13=-1.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=0.
elif j == 12:
Name1='B'
Name2='C'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=-1.
elif j == 13:
Name1='A'
Name2='D'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=-1. #
Coeff22=1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=-1.
elif j == 14:
Name1='C'
Name2='C1'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=1.
Coeff31=1. #
Coeff32=-1.
Coeff33=-0.
elif j == 15:
Name1='D'
Name2='D1'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=1.
Coeff31=1. #
Coeff32=-1.
Coeff33=-0.
elif j == 16:
Name1='C1'
Name2='B1'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=1.
elif j == 17:
Name1='D1'
Name2='A1'
Coeff11=1.
Coeff12=-1.
Coeff13=0.
Coeff21=1. #
Coeff22=-1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=1.
elif j == 18:
Name1='A1'
Name2='B1'
Coeff11=-1.
Coeff12=1.
Coeff13=-1.
Coeff21=-1. #
Coeff22=1.
Coeff23=0.
Coeff31=1. #
Coeff32=-1.
Coeff33=0.
i=1
entity1=zAssembly.sets[Name1].nodes
entity2=zAssembly.sets[Name2].nodes
for eachNode1 in entity1:
cor1x=eachNode1.coordinates[0]
cor1y=eachNode1.coordinates[1]
cor1z=eachNode1.coordinates[2]
for eachNode2 in entity2:
distx=abs(cor1x-eachNode2.coordinates[0])
disty=abs(cor1y-eachNode2.coordinates[1])
distz=abs(cor1z-eachNode2.coordinates[2])
if (distx<Toler and disty<Toler)or(disty<Toler and distz<Toler)or(distx<Toler and distz<Toler):
Node1=entity1.sequenceFromLabels(labels=(eachNode1.label,))
Node2=entity2.sequenceFromLabels(labels=(eachNode2.label,))
zAssembly.Set(name='S'+Name1+str(i),nodes=Node1)
zAssembly.Set(name='S'+Name2+str(i),nodes=Node2)
zModel.Equation(name=Name1+Name2+'1'+str(i),terms=((Coeff11,'S'+Name1+str(i),1),(Coeff12,'S'+Name2+str(i),1),(Coeff13,'Dummy',1)))
zModel.Equation(name=Name1+Name2+'2'+str(i),terms=((Coeff21,'S'+Name1+str(i),2),(Coeff22,'S'+Name2+str(i),2),(Coeff23,'Dummy',2)))
zModel.Equation(name=Name1+Name2+'3'+str(i),terms=((Coeff31,'S'+Name1+str(i),3),(Coeff32,'S'+Name2+str(i),3),(Coeff33,'Dummy',3)))
i=i+1

View file

@ -0,0 +1,14 @@
from abaqusConstants import *
from abaqus import *
aModel=mdb.models['3D_Rad']
aAss=aMode.rootAsembly
aPart=aModel.parts['Mesh']
aSet=aAss.sets['Set-1']
aInst=aAss.instances['Mesh-1']
for eachnode in aSet.nodes:
theta=eachnode.coordinates[1]/Radius
newcoord1=eachnode.coordinates[0]
newcoord2=(Radius-eachnode.coordinates[2])*cos(theta)
newcoord3=(Radius-eachnode.coordinates[2])*sin(theta)
aPart.editNode(nodes=eachnode,coordinate1=newcoord1,coordinate2=newcoord2,
coordinate3=newcoord3)

0
Unpublished/README.md Normal file
View file

View file

@ -0,0 +1,64 @@
subroutine rsurfu(h,p,tgt,dnds,x1,time,u,ciname,slname,msname,
1 noel,node,lclose)
include 'aba_param.inc'
c
character*80 ciname,slname,msname
dimension p(3),tgt(3,2),dnds(3,2),x1(3,2),time(2)
parameter(zero=0.d0,one=1.d0)
c get cylinder radius
stime=time(2)
if(msname(1:5)=='INNER')then
ri=0.4d0
drdt=one
if(stime<=one)then
radius=ri+drdt*stime
elseif(stime<=2.d0)then
radius=ri+drdt*(2.d0-stime)
else
radius=ri
endif
else
ri=1.8d0
drdt=-one
if(stime>=2.0d0)then
radius=ri+drdt*(stime-2.0d0)
else
radius=ri
endif
endif
c initialize variables
do k1=1,2
do k2=1,3
tgt(k2,k1) = zero
dnds(k2,k1) = zero
p(k2) = zero
enddo
enddo
c coordinates of point on deforming body
x = x1(1,1)
y = x1(2,1)
z = x1(3,1)
c project point onto unit radius cylinder
r = ( x*x + y*y )**(0.5d0)
x = x / r
y = y / r
c get point on rigid cylinder
p(1) = radius*x
p(2) = radius*y
p(3) = z
c get unit tangents
tgt(1,1) = -y
tgt(2,1) = x
tgt(3,2) = one
c get local curvatures
dnds(1,1) = -y / radius
dnds(2,1) = x / radius
c get surface penetration depth
if(msname(1:5)=='INNER')then
h = radius - r
else
h = r - radius
endif
print *,radius,stime,msname(1:5),h
return
end

View file

@ -0,0 +1,102 @@
subroutine rsurfu(h,p,tgt,dnds,x1,time,u,ciname,slname,msname,
1 noel,node,lclose)
include 'aba_param.inc'
c
character*80 ciname,slname,msname
dimension p(3),tgt(3,2),dnds(3,2),x1(3,2),time(2)
parameter(zero=0.d0,one=1.d0)
c get cylinder radius
stime=time(2)
if(msname(1:5)=='INNER')then
ri=0.4d0
drdt=one
if(stime<=one)then
radius=ri+drdt*stime
elseif(stime<=2.d0)then
radius=ri+drdt*(2.d0-stime)
else
radius=ri
endif
else
ri=1.8d0
drdt=-one
if(stime>=3.05d0)then
radius=ri+drdt*(stime-3.05d0)
else
radius=ri
endif
endif
c initialize variables
do k1=1,2
do k2=1,3
tgt(k2,k1) = zero
dnds(k2,k1) = zero
p(k2) = zero
enddo
enddo
c coordinates of point on deforming body
x = x1(1,1)
y = x1(2,1)
z = x1(3,1)
c get point on rigid cylinder
x2=x1(1,1)+x1(1,3)
y2=x1(2,1)+x1(2,3)
z2=x1(3,1)+x1(3,3)
dx=x2-x
dy=y2-y
dr=sqrt(dx*dx+dy*dy)
D=x*y2-x2*y
disc=radius*radius*dr*dr-D*D
if(disc==zero)then
xcor=D*dy/(dr*dr)
ycor=-D*dx/(dr*dr)
elseif(disc<zero)then
xcor=1.e6
ycor=1.e6
print *,'warning - perpendicular slave master normals'
else
x1cor=(d*dy+sign(one,dy)*dx*disc)/(dr*dr)
x2cor=(d*dy-sign(one,dy)*dx*disc)/(dr*dr)
y1cor=(-d*dx+abs(dy)*disc)/(dr*dr)
y2cor=(-d*dx-abs(dy)*disc)/(dr*dr)
dx1=x1cor-x
dx2=x2cor-x2
dy1=y1cor-y
dy2=y2cor-y2
d1=sqrt(dx1*dx1+dy1*dy1)
d2=sqrt(dx2*dx2+dy2*dy2)
z1cor=x1(3,3)*d1+z
z2cor=x1(3,3)*d2+z
dz1=z1cor-z
dz2=z2cor-z2
dist1=sqrt(dx1*dx1+dy1*dy1+dz1*dz1)
dist2=sqrt(dx2*dx2+dy2*dy2+dz2*dz2)
if(dist1<dist2)then
p(1) = x1cor
p(2) = y1cor
p(3) = z1cor
else
p(1) = x2cor
p(2) = y2cor
p(3) = z2cor
endif
endif
c project point onto unit radius cylinder
r = ( x*x + y*y )**(0.5d0)
x = p(1)/radius
y = p(2)/radius
c get unit tangents
tgt(1,1) = -y
tgt(2,1) = x
tgt(3,2) = one
c get local curvatures
dnds(1,1) = -y / radius
dnds(2,1) = x / radius
c get surface penetration depth
if(msname(1:5)=='INNER')then
h = radius - r
else
h = r - radius
endif
return
end

View file

@ -0,0 +1,234 @@
function [] = 2DLevelSet()
clear all
% Define Main Solution Mesh
NumX=8;
NumY=8;
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);
% 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:1.:8);
Z=zeros(9);
for i=1:81
Z(i)=lSet(i);
end
surf(X,Y,Z)
% LS Algorithm Parameters
lSet'
bandwidth=10.;
% Loop through timesteps
for tstep=1:100
% Identify Narrow Band Elements
NBindex=0;
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
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,2);
NBelem(NBindex,3)=Element(i,3);
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,3);
NBelem(NBindex,3)=Element(i,4);
end
end
% Velocity BC
F=zeros(numNodes,1);
for i=1:NBindex
if sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,2)))||sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,3)))
F(NBelem(i,1))= 1.;
F(NBelem(i,2))= 1.;
F(NBelem(i,3))= 1.;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numNodes);
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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(numNodes,1);
Sub=A*F;
iindex=0;
for i=1:numNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numNodes
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:numNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numNodes);
mMatGLS=zeros(numNodes);
f1=zeros(numNodes,1);
f2=zeros(numNodes,1);
f3=zeros(numNodes,1);
h2=0.00001;
visc=0.0005;
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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;
lSet=lSet-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))';
end
lSet'
%[X Y]=meshgrid(0:1.:8);
%Z=zeros(9);
%for i=1:81
% Z(i)=lSet(i);
%end
%surf(X,Y,Z)

View file

@ -0,0 +1,234 @@
function [] = 2DLevelSetFMM()
clear all
% Define Main Solution 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);
% 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:1.:8);
%Z=zeros(9);
%for i=1:81
% Z(i)=lSet(i);
%end
%surf(X,Y,Z)
% LS Algorithm Parameters
lSet'
bandwidth=10.;
% Loop through timesteps
for tstep=1:1
% Identify Narrow Band Elements
NBindex=0;
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
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,2);
NBelem(NBindex,3)=Element(i,3);
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,3);
NBelem(NBindex,3)=Element(i,4);
end
end
% Velocity BC
F=zeros(numNodes,1);
for i=1:NBindex
if sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,2)))||sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,3)))
F(NBelem(i,1))= 1.;
F(NBelem(i,2))= 1.;
F(NBelem(i,3))= 1.;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numNodes);
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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(numNodes,1);
Sub=A*F;
iindex=0;
for i=1:numNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numNodes
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:numNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numNodes);
mMatGLS=zeros(numNodes);
f1=zeros(numNodes,1);
f2=zeros(numNodes,1);
f3=zeros(numNodes,1);
h2=0.00001;
visc=0.0005;
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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;
lSet=lSet-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))';
end
lSet'
%[X Y]=meshgrid(0:1.:8);
%Z=zeros(9);
%for i=1:81
% Z(i)=lSet(i);
%end
%surf(X,Y,Z)

View file

@ -0,0 +1,322 @@
function [] = F2DLevelSetFMM()
clear all
% Define Main Solution Mesh
NumX=5;
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);
% 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:1.:8);
%Z=zeros(9);
%for i=1:81
% Z(i)=lSet(i);
%end
%surf(X,Y,Z)
% LS Algorithm Parameters
lSet'
bandwidth=3.;
% Loop through timesteps
for tstep=1:1
% 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 NewNums(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:NBindex
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(lSet(NBelem(i,j)))<=lmin
check=1;
tempindex=j;
end
end
ltot=ltot+abs(lSet(NBelem(i,j)));
end
if check==1 & ltot/3.<=avlmin
eindex=i;
nindex=tempindex;
lmin=lSet(NBelem(eindex,nindex));
avlmin=ltot/3.;
end
end
end
if maincheck==0
% Find New LS for point
xp=Node(NBelem(eindex,nindex),1);
yp=Node(NBelem(eindex,nindex),2);
count=0;
for i=1:3
if i~=nindex
count=count+1;
x(count)=Node(NBelem(eindex,i),1);
y(count)=Node(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
% lSet=newlSet;
end
lSet'

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,221 @@
function [] = FESolveX()
% MATLAB based XFEM Solver
% J. Grogan (2012)
clear all
% Define Geometry
len=10.;
% Define Section Properties
rho=1.;
% Generate Mesh
numElem=10;
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=5.;
% Initial temperatures
Tnew=zeros(numNodes*2,1);
%storage
stored(1)=dpos;
for e=1:numElem
crdn1=ndCoords(elemNodes(e,1));
if crdn1<=dpos
Tnew(2*elemNodes(e,1)-1)=1.;
end
end
% Define Time Step
dtime=0.05;
tsteps=20;
time=0.;
% penalty term
beta=40.;
% 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/charlen)*(2*t(1)+t(2)-t(3)-2*t(4));
% 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.);
fdofs(1)=2*elemNodes(e,1);
fdofs(2)=2*elemNodes(e,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.;
spec=0.01;
else
cond=1.;
spec=1.;
end
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
% 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)));
tpos=gm(1)*Tnew(1)+gm(2)*Tnew(2)+gm(3)*Tnew(3)+gm(4)*Tnew(4);
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 inactive DOFs(Reduce Matrices)
T1=1;
RHS=M*Tnew;
iindex=0;
for i=1:ndof*numNodes;
check=1;
if i==fdofs(1)|i==fdofs(2)
check=0;
elseif mod(i,2)~=0 & i~=1
check=0;
end
if check==0
jindex=0;
iindex=iindex+1;
for j=1:ndof*numNodes;
check=1;
if j==fdofs(1)|j==fdofs(2)
check=0;
elseif mod(j,2)~=0 & j~=1
check=0;
end
if check==0
jindex=jindex+1;
Kred(iindex,jindex)=K(i,j);
Mred(iindex,jindex)=M(i,j);
end
end
Subr(iindex)=(K(i,1)+M(i,1))*T1;
RHSr(iindex)=RHS(i);
pforcer(iindex)=pforce(i);
end
end
%Solve
Mred+Kred;
StiffI=(Mred+Kred)^-1;
Tnewr=StiffI*(RHSr'-Subr'+pforcer');
iindex=0.;
for i=1:ndof*numNodes;
check=1;
if i==fdofs(1)|i==fdofs(2)
check=0;
elseif mod(i,2)~=0 & i~=1
check=0;
end
if check==0
iindex=iindex+1;
Tnew(i)=Tnewr(iindex);
else
Tnew(i)=0.;
end
end
Tnew(1)=1.;
Tnew
end
stored'

View file

@ -0,0 +1,128 @@
function [] = GetF()
% set up grid
gd=0.;
numElem=4;
eLen=0.25;
for i=1:numElem+1
ndCrd(i)=gd;
gd=gd+eLen;
end
for i=1:numElem
elemNod(i,1)=i;
elemNod(i,2)=i+1;
end
% Initial level set
dpos=0.1;
for i=1:numElem+1
lSet(i)=sign(ndCrd(i)-dpos)*abs(dpos-ndCrd(i));
end
lSet'
for tstep=1:1
% Velocity BC
F=zeros(numElem+1,1);
for i=1:numElem
if sign(lSet(elemNod(i,1)))~=sign(lSet(elemNod(i,2)))
F(elemNod(i,1))= 0.0005;
F(elemNod(i,2))= 0.0005;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numElem+1);
for i=1:numElem
pos(1)=-1/sqrt(3);
pos(2)=1/sqrt(3);
AfL=zeros(2);
AfLGLS=zeros(2);
for j=1:2
shp(1)=(1-pos(j))/2.;
shp(2)=(1+pos(j))/2.;
dshp(1)=-0.5;
dshp(2)=0.5;
rset=shp(1)*lSet(elemNod(i,1))+shp(2)*lSet(elemNod(i,2));
dls=dshp(1)*lSet(elemNod(i,1))+dshp(2)*lSet(elemNod(i,2));
AfL=AfL+shp'*sign(rset)*(dls*dshp);
AfLGLS=AfLGLS+(dshp'*dls)*(0.25/abs(dls))*(dls*dshp);
end
for k=1:2;
for j=1:2;
A(elemNod(i,j),elemNod(i,k))=A(elemNod(i,j),elemNod(i,k))+AfL(j,k)+AfLGLS(j,k)
end
end
end
% Apply BCs
RHS=zeros(numElem+1,1);
Sub=A*F;
iindex=0;
for i=1:numElem+1
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numElem+1
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:numElem+1
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numElem+1);
mMatGLS=zeros(numElem+1);
f1=zeros(numElem+1,1);
f2=zeros(numElem+1,1);
f3=zeros(numElem+1,1);
h=0.25;
visc=0.000;
for i=1:numElem
pos(1)=-1/sqrt(3);
pos(2)=1/sqrt(3);
mMatL=zeros(2);
mMatGLSL=zeros(2);
f1L=zeros(2,1);
f2L=zeros(2,1);
f3L=zeros(2,1);
for j=1:2
shp(1)=(1-pos(j))/2.;
shp(2)=(1+pos(j))/2.;
dshp(1)=-0.5;
dshp(2)=0.5;
Floc=shp(1)*F(elemNod(i,1))+shp(2)*F(elemNod(i,2));
rset=shp(1)*lSet(elemNod(i,1))+shp(2)*lSet(elemNod(i,2));
dls=dshp(1)*lSet(elemNod(i,1))+dshp(2)*lSet(elemNod(i,2));
mMatL=mMatL+shp'*shp;
mMatGLSL=mMatGLSL+((dshp'*(dls/abs(dls)))*Floc*(h/abs(Floc)))*shp;
f1L=f1L+shp'*Floc*abs(dls);
f2L=f2L+(dshp'*(dls/abs(dls))*Floc)*(h/abs(Floc))*Floc*abs(dls);
vs=h*((abs(visc+Floc*abs(dls)))/(abs(Floc*dls)+h));
f3L=f3L+vs*dshp'*dls;
end
for k=1:2;
for j=1:2;
mMat(elemNod(i,j),elemNod(i,k))=mMat(elemNod(i,j),elemNod(i,k))+mMatL(j,k);
mMatGLS(elemNod(i,j),elemNod(i,k))=mMatGLS(elemNod(i,j),elemNod(i,k))+mMatGLSL(j,k);
end
f1(elemNod(i,k))=f1(elemNod(i,k))+f1L(k);
f2(elemNod(i,k))=f2(elemNod(i,k))+f2L(k);
f3(elemNod(i,k))=f3(elemNod(i,k))+f3L(k);
end
end
dt=0.01;
lSet=lSet-((((mMat+mMatGLS)^-1)/dt)*(f1+f2+f3))';
lSet';
end

View file

@ -0,0 +1,200 @@
function [] = GetF2D_()
clear all
% Define Main Solution Mesh
NumX=10;
NumY=10;
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);
% Define Initial Level Set
centx=5.;
centy=5.;
rad=2.5;
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
% Plot initial level set
[X,Y]=meshgrid(0:1.:10);
Z=zeros(11);
for i=1:numNodes
Z(i)=lSet(i);
end
surf(X,Y,Z)
% LS Algorithm Parameters
bandwith=10.;
% Loop through timesteps
for tstep=1:1
% Identify Narrow Band Elements
NBindex=0;
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
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,2);
NBelem(NBindex,3)=Element(i,3);
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,3);
NBelem(NBindex,3)=Element(i,4);
end
end
% Velocity BC
F=zeros(numNodes,1);
for i=1:NBindex
if lSet(NBelem(i,1))~=lSet(NBelem(i,2)) || lSet(NBelem(i,1))~=lSet(NBelem(i,3))
F(NBelem(i,1))= 0.0005;
F(NBelem(i,2))= 0.0005;
F(NBelem(i,3))= 0.0005;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numNodes);
for i=1:NBindex
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;
AfL=zeros(4);
AfLGLS=zeros(4);
for j=1:4
g=gx(j);
h=hx(j);
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);
phig(1)=0.25*-(1.-h);
phig(2)=0.25*(1.-h);
phig(3)=0.25*(1.+h);
phig(4)=0.25*-(1.+h);
rset=phi(1)*lSet(Element(i,1))+phi(2)*lSet(Element(i,2))+phi(3)*lSet(Element(i,3))+phi(4)*lSet(Element(i,4));
dls=phig(1)*lSet(Element(i,1))+phig(2)*lSet(Element(i,2))+phig(3)*lSet(Element(i,3))+phig(4)*lSet(Element(i,4));
AfL=AfL+(phi'*sign(rset))*(dls*phig);
AfLGLS=AfLGLS+(phig'*dls)*(1./abs(dls))*(dls*phig);
end
for k=1:4;
for j=1:4;
A(Element(i,j),Element(i,k))=A(Element(i,j),Element(i,k))+AfL(j,k)+AfLGLS(j,k);
end
end
end
% Apply BCs
RHS=zeros(numNodes,1);
Sub=A*F;
iindex=0;
for i=1:numNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numNodes
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:numNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numNodes);
mMatGLS=zeros(numNodes);
f1=zeros(numNodes,1);
f2=zeros(numNodes,1);
f3=zeros(numNodes,1);
h=1.;
visc=0.000;
for i=1:numElem
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;
mMatL=zeros(4);
mMatGLSL=zeros(4);
f1L=zeros(4,1);
f2L=zeros(4,1);
f3L=zeros(4,1);
for j=1:4
g=gx(j);
h=hx(j);
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);
phig(1)=0.25*-(1.-h);
phig(2)=0.25*(1.-h);
phig(3)=0.25*(1.+h);
phig(4)=0.25*-(1.+h);
Floc=phi(1)*F(Element(i,1))+phi(2)*F(Element(i,2))+phi(3)*F(Element(i,3))+phi(4)*F(Element(i,4));
rset=phi(1)*lSet(Element(i,1))+phi(2)*lSet(Element(i,2))+phi(3)*lSet(Element(i,3))+phi(4)*lSet(Element(i,4));
dls=phig(1)*lSet(Element(i,1))+phig(2)*lSet(Element(i,2))+phig(3)*lSet(Element(i,3))+phig(4)*lSet(Element(i,4));
mMatL=mMatL+phi'*phi;
mMatGLSL=mMatGLSL+((phig'*(dls/abs(dls)))*Floc*(h/abs(Floc)))*phi;
f1L=f1L+phi'*Floc*abs(dls);
f2L=f2L+(phig'*(dls/abs(dls))*Floc)*(h/abs(Floc))*Floc*abs(dls);
vs=h*((abs(visc+Floc*abs(dls)))/(abs(Floc*dls)+h));
f3L=f3L+vs*phig'*dls;
end
for k=1:4;
for j=1:4;
mMat(Element(i,j),Element(i,k))=mMat(Element(i,j),Element(i,k))+mMatL(j,k);
mMatGLS(Element(i,j),Element(i,k))=mMatGLS(Element(i,j),Element(i,k))+mMatGLSL(j,k);
end
f1(Element(i,k))=f1(Element(i,k))+f1L(k);
f2(Element(i,k))=f2(Element(i,k))+f2L(k);
f3(Element(i,k))=f3(Element(i,k))+f3L(k);
end
end
dt=0.01;
lSet=lSet-((((mMat+mMatGLS)^-1)/dt)*(f1+f2+f3))';
end
%scatter3(Node(:,1), Node(:,2), lSet');

View file

@ -0,0 +1,200 @@
function [] = GetF2D()
clear all
% Define Main Solution Mesh
NumX=10;
NumY=10;
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);
% Define Initial Level Set
centx=5.;
centy=5.;
rad=2.5;
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
% Plot initial level set
[X,Y]=meshgrid(0:1.:10);
Z=zeros(11);
for i=1:numNodes
Z(i)=lSet(i);
end
surf(X,Y,Z)
% LS Algorithm Parameters
bandwith=10.;
% Loop through timesteps
for tstep=1:1
% Identify Narrow Band Elements
NBindex=0;
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
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,2);
NBelem(NBindex,3)=Element(i,3);
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,3);
NBelem(NBindex,3)=Element(i,4);
end
end
% Velocity BC
F=zeros(numNodes,1);
for i=1:NBindex
if lSet(NBelem(i,1))~=lSet(NBelem(i,2)) || lSet(NBelem(i,1))~=lSet(NBelem(i,3))
F(NBelem(i,1))= 0.0005;
F(NBelem(i,2))= 0.0005;
F(NBelem(i,3))= 0.0005;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numNodes);
for i=1:NBindex
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;
AfL=zeros(4);
AfLGLS=zeros(4);
for j=1:4
g=gx(j);
h=hx(j);
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);
phig(1)=0.25*-(1.-h);
phig(2)=0.25*(1.-h);
phig(3)=0.25*(1.+h);
phig(4)=0.25*-(1.+h);
rset=phi(1)*lSet(Element(i,1))+phi(2)*lSet(Element(i,2))+phi(3)*lSet(Element(i,3))+phi(4)*lSet(Element(i,4));
dls=phig(1)*lSet(Element(i,1))+phig(2)*lSet(Element(i,2))+phig(3)*lSet(Element(i,3))+phig(4)*lSet(Element(i,4));
AfL=AfL+(phi'*sign(rset))*(dls*phig);
AfLGLS=AfLGLS+(phig'*dls)*(1./abs(dls))*(dls*phig);
end
for k=1:4;
for j=1:4;
A(Element(i,j),Element(i,k))=A(Element(i,j),Element(i,k))+AfL(j,k)+AfLGLS(j,k)
end
end
end
% Apply BCs
RHS=zeros(numNodes,1);
Sub=A*F;
iindex=0;
for i=1:numNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numNodes
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:numNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numNodes);
mMatGLS=zeros(numNodes);
f1=zeros(numNodes,1);
f2=zeros(numNodes,1);
f3=zeros(numNodes,1);
h=1.;
visc=0.000;
for i=1:numElem
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;
mMatL=zeros(4);
mMatGLSL=zeros(4);
f1L=zeros(4,1);
f2L=zeros(4,1);
f3L=zeros(4,1);
for j=1:4
g=gx(j);
h=hx(j);
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);
phig(1)=0.25*-(1.-h);
phig(2)=0.25*(1.-h);
phig(3)=0.25*(1.+h);
phig(4)=0.25*-(1.+h);
Floc=phi(1)*F(Element(i,1))+phi(2)*F(Element(i,2))+phi(3)*F(Element(i,3))+phi(4)*F(Element(i,4));
rset=phi(1)*lSet(Element(i,1))+phi(2)*lSet(Element(i,2))+phi(3)*lSet(Element(i,3))+phi(4)*lSet(Element(i,4));
dls=phig(1)*lSet(Element(i,1))+phig(2)*lSet(Element(i,2))+phig(3)*lSet(Element(i,3))+phig(4)*lSet(Element(i,4));
mMatL=mMatL+phi'*phi;
mMatGLSL=mMatGLSL+((phig'*(dls/abs(dls)))*Floc*(h/abs(Floc)))*phi;
f1L=f1L+phi'*Floc*abs(dls);
f2L=f2L+(phig'*(dls/abs(dls))*Floc)*(h/abs(Floc))*Floc*abs(dls);
vs=h*((abs(visc+Floc*abs(dls)))/(abs(Floc*dls)+h));
f3L=f3L+vs*phig'*dls;
end
for k=1:4;
for j=1:4;
mMat(Element(i,j),Element(i,k))=mMat(Element(i,j),Element(i,k))+mMatL(j,k);
mMatGLS(Element(i,j),Element(i,k))=mMatGLS(Element(i,j),Element(i,k))+mMatGLSL(j,k);
end
f1(Element(i,k))=f1(Element(i,k))+f1L(k);
f2(Element(i,k))=f2(Element(i,k))+f2L(k);
f3(Element(i,k))=f3(Element(i,k))+f3L(k);
end
end
dt=0.01;
lSet=lSet-((((mMat+mMatGLS)^-1)/dt)*(f1+f2+f3))';
end
%scatter3(Node(:,1), Node(:,2), lSet');

View file

@ -0,0 +1,232 @@
function [] = GetF2D_T()
clear all
% Define Main Solution Mesh
NumX=2;
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);
% Define Initial Level Set
%centx=5.;
%centy=5.;
%rad=2.5;
%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]=meshgrid(0:1.:10);
%Z=zeros(11);
%for i=1:numNodes
% Z(i)=lSet(i);
%end
%surf(X,Z)
% LS Algorithm Parameters
bandwidth=10.;
% Loop through timesteps
for tstep=1:1
% Identify Narrow Band Elements
NBindex=0;
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
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,2);
NBelem(NBindex,3)=Element(i,3);
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,3);
NBelem(NBindex,3)=Element(i,4);
end
end
% Velocity BC
F=zeros(numNodes,1);
for i=1:NBindex
if sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,2)))||sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,3)))
F(NBelem(i,1))= 0.05;
F(NBelem(i,2))= 0.05;
F(NBelem(i,3))= 0.05;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numNodes);
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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(numNodes,1);
Sub=A*F;
iindex=0;
for i=1:numNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numNodes
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:numNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numNodes);
mMatGLS=zeros(numNodes);
f1=zeros(numNodes,1);
f2=zeros(numNodes,1);
f3=zeros(numNodes,1);
h=1.;
visc=0.001;
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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*(h/abs(Floc)))*phi/3.;
f1L=f1L+phi'*Floc*norm(delset)/3.;
f2L=f2L+(delphi'*(delset/norm(delset))*Floc)*(h/abs(Floc))*Floc*norm(delset)/3.;
vs=h*((abs(visc+Floc*norm(delset)))/(norm(Floc*delset)+h));
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
(mMat+mMatGLS)^-1
f1+f2+f3
dt=0.0001;
-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))'
lSet=lSet-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))';
end
lSet';
%scatter3(Node(:,1), Node(:,2), lSet');

View file

@ -0,0 +1,233 @@
function [] = GetF2D_T()
clear all
% Define Main Solution Mesh
NumX=2;
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);
% Define Initial Level Set
%centx=5.;
%centy=5.;
%rad=2.5;
%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.5;
lSet(i)=dist;
end
% Plot initial level set
%[X]=meshgrid(0:1.:10);
%Z=zeros(11);
%for i=1:numNodes
% Z(i)=lSet(i);
%end
%surf(X,Z)
% LS Algorithm Parameters
bandwidth=10.;
% Loop through timesteps
for tstep=1:1
% Identify Narrow Band Elements
NBindex=0;
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
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,2);
NBelem(NBindex,3)=Element(i,3);
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,3);
NBelem(NBindex,3)=Element(i,4);
end
end
% Velocity BC
F=zeros(numNodes,1);
for i=1:NBindex
if sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,2)))||sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,3)))
F(NBelem(i,1))= 0.05;
F(NBelem(i,2))= 0.05;
F(NBelem(i,3))= 0.05;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numNodes);
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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(numNodes,1);
Sub=A*F;
iindex=0;
for i=1:numNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numNodes
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:numNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numNodes);
mMatGLS=zeros(numNodes);
f1=zeros(numNodes,1);
f2=zeros(numNodes,1);
f3=zeros(numNodes,1);
h=1.;
visc=0.0005;
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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*(h/abs(Floc)))*phi/3.;
f1L=f1L+phi'*Floc*norm(delset)/3.;
f2L=f2L+(delphi'*(delset/norm(delset))*Floc)*(h/abs(Floc))*Floc*norm(delset)/3.;
vs=h*((abs(visc+Floc*norm(delset)))/(norm(Floc*delset)+h));
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
mMat
mMatGLS
(mMat+mMatGLS)^-1
f1+f2+f3
dt=0.1;
-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))'
lSet=lSet-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))';
end
lSet';
%scatter3(Node(:,1), Node(:,2), lSet');

View file

@ -0,0 +1,234 @@
function [] = GetF2D_Z()
clear all
% Define Main Solution Mesh
NumX=8;
NumY=8;
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);
% 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:1.:8);
Z=zeros(9);
for i=1:81
Z(i)=lSet(i);
end
surf(X,Y,Z)
% LS Algorithm Parameters
lSet'
bandwidth=10.;
% Loop through timesteps
for tstep=1:100
% Identify Narrow Band Elements
NBindex=0;
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
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,2);
NBelem(NBindex,3)=Element(i,3);
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,3);
NBelem(NBindex,3)=Element(i,4);
end
end
% Velocity BC
F=zeros(numNodes,1);
for i=1:NBindex
if sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,2)))||sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,3)))
F(NBelem(i,1))= 1.;
F(NBelem(i,2))= 1.;
F(NBelem(i,3))= 1.;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numNodes);
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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(numNodes,1);
Sub=A*F;
iindex=0;
for i=1:numNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numNodes
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:numNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numNodes);
mMatGLS=zeros(numNodes);
f1=zeros(numNodes,1);
f2=zeros(numNodes,1);
f3=zeros(numNodes,1);
h2=0.00001;
visc=0.0005;
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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;
lSet=lSet-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))';
end
lSet'
%[X Y]=meshgrid(0:1.:8);
%Z=zeros(9);
%for i=1:81
% Z(i)=lSet(i);
%end
%surf(X,Y,Z)

View file

@ -0,0 +1,2 @@
function [] = testGrid()

View file

@ -0,0 +1,4 @@
function [] = testGrid()
[X,Y]=meshgrid(1:1:10);
Z=2*X+Y
surf(X,Y,Z)

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

View file

@ -0,0 +1,546 @@
C
C User element accessing Abaqus materials
C Heat Transfer -- conduction
C
c*****************************************************************
subroutine uelmat(rhs, amatrx, svars, energy, ndofel, nrhs,
1 nsvars, props, nprops, coords, mcrd, nnode, u, du, v, a, jtype,
2 time, dtime, kstep, kinc, jelem, params, ndload, jdltyp, adlmag,
3 predef, npredf, lflags, mlvarx, ddlmag, mdload, pnewdt, jprops,
4 njpro, period, materiallib)
c
include 'aba_param.inc'
C
dimension rhs(mlvarx,*), amatrx(ndofel, ndofel), props(*),
1 svars(*), energy(*), coords(mcrd, nnode), u(ndofel),
2 du(mlvarx,*), v(ndofel), a(ndofel), time(2), params(*),
3 jdltyp(mdload,*), adlmag(mdload,*), ddlmag(mdload,*),
4 predef(2, npredf, nnode), lflags(*), jprops(*)
c
c local arrays
c
parameter (zero=0.d0, one=1.d0)
parameter (ndim=2, ndof=1, ninpt=4, nnodemax=4)
c
c ndim ... number of spatial dimensions
c ndof ... number of degrees of freedom per node
c ninpt ... number of integration points
c
dimension stiff(ndof*nnodemax,ndof*nnodemax),
1 force(ndof*nnodemax), shape(nnodemax), dshape(ndim,nnodemax),
2 xjaci(ndim,ndim), bmat(nnodemax*ndim), wght(ninpt)
dimension coords_ip(3),dfgrd0(3,3),dfgrd1(3,3),
1 drot(3,3)
dimension coords_new(mcrd,nnodemax)
c
dimension predef_loc(npredf),dpredef_loc(npredf),xx1(3,3),
1 xx1Old(3,3)
dimension xjaci_new(ndim,ndim),bmat_new(nnodemax*ndim)
dimension dtemdx(ndim),rhoUdotdg(3),flux(ndim),dfdt(ndim),
1 dfdg(ndim,ndim)
c
data wght /one, one, one, one/
c
c********************************************************************
c
c U1 = first-order, plane strain, full integration
c
c********************************************************************
if (lflags(3).eq.4) goto 999
c
c Preliminaries
c
pnewdtLocal = pnewdt
if(jtype .ne. 1) then
write(7,*)'Incorrect element type'
call xit
endif
c
c initialize rhs and lhs
c
do k1=1, ndof*nnode
rhs(k1, 1)= zero
do k2=1, ndof*nnode
amatrx(k1, k2)= zero
end do
end do
c
do k1=1,nnode
do k2=1,mcrd
kk = (k1-1)*mcrd + k2
coords_new(k2,k1) = coords(k2,k1) + u(kk)
end do
end do
c
c loop over integration points
c
do kintk = 1, ninpt
c
c initialization
c
rho = zero
rhoUdot = zero
rhoUdotdt = zero
rhoUdotdg = zero
do i=1, 3
rhoUdotdg(i) = zero
end do
do i=1, ndim
flux(i) = zero
dfdt(i) = zero
end do
do i=1, ndim
do j=1, ndim
dfdg(i,j) = zero
end do
end do
c
c evaluate shape functions and derivatives
c
call shapefcn(kintk,ninpt,nnode,ndim,shape,dshape)
c
c compute coordinates at the integration point
c
do k1=1, 3
coords_ip(k1) = zero
end do
do k1=1,nnode
do k2=1,mcrd
coords_ip(k2)=coords_ip(k2)+shape(k1)*coords(k2,k1)
end do
end do
c
if(npredf.gt.0) then
call tempfv(kintk,ninpt,nnode,ndim,shape,predef,
* npredf,predef_loc,dpredef_loc)
end if
c
c form B-matrix
c
djac = one
djac_new = one
call jacobian(jelem,mcrd,ndim,nnode,coords,dshape,
1 djac,xjaci,pnewdt,coords_new,xjaci_new,djac_new)
c
if (pnewdt .lt. pnewdtLocal) pnewdtLocal = pnewdt
c
call bmatrix(xjaci,dshape,nnode,ndim,bmat,xjaci_new,
1 bmat_new)
c
c compute temp. and temp. gradient
c
temp = zero
dtemp = zero
call settemp(ndofel,ndof,ndim,nnode,mlvarx,bmat,du,
* dstran,u,xx1,xx1Old,temp,dtemp,dtemdx,shape)
c
c get Abaqus material
c
rpl = zero
drpldt = zero
celent = one
call material_lib_ht(materiallib,rhoUdot,rhoUdotdt,rhoUdotdg,
* flux,dfdt,dfdg,rpl,drpldt,kintk,djac,predef_loc,
* dpredef_loc,npredf,temp,dtemp,dtemdx,celent,coords_ip)
c
c
c form stiffness matrix and internal force vector
c
call rhsjacobian(nnode,ndim,ndof,
1 wght(kintk),djac,rhoUdot,rhoUdotdt,rhoUdotdg,flux,
2 dfdt,dfdg,shape,bmat,stiff,force,dtime,lflags)
c
c assemble rhs and lhs
c
do k1=1, ndof*nnode
rhs(k1, 1) = rhs(k1, 1) - force(k1)
do k2=1, ndof*nnode
amatrx(k1, k2) = amatrx(k1, k2) + stiff(k1,k2)
end do
end do
end do ! end loop on material integration points
pnewdt = pnewdtLocal
c
999 continue
c
return
end
c*****************************************************************
c
c Compute shape fuctions
c
subroutine shapefcn(kintk,ninpt,nnode,ndim,dN,dNdz)
c
include 'aba_param.inc'
c
parameter (dmone=-1.0d0,one=1.0d0,four=4.0d0,eight=8.0d0,
1 gaussCoord=0.577350269d0)
parameter (maxElemNode=8,maxDof=3,i2d4node=24,i3d8node=38)
dimension dN(*),dNdz(ndim,*),coord24(2,4),coord38(3,8)
c
data coord24 /dmone, dmone,
2 one, dmone,
3 one, one,
4 dmone, one/
c
data coord38 /dmone, dmone, dmone,
2 one, dmone, dmone,
3 one, one, dmone,
4 dmone, one, dmone,
5 dmone, dmone, one,
6 one, dmone, one,
7 one, one, one,
8 dmone, one, one/
C
iCode = 0
if (ninpt.eq.4.and.nnode.eq.4.and.ndim.eq.2) then
iCode = 24
else if (ninpt.eq.8.and.nnode.eq.8.and.ndim.eq.3) then
iCode = 38
else
write (6,*) '***ERROR: The shape fuctions cannot be found'
end if
C
C 3D 8-nodes
C
if (iCode.eq.i3d8node) then
c
c determine (g,h,r)
c
g = coord38(1,kintk)*gaussCoord
h = coord38(2,kintk)*gaussCoord
r = coord38(3,kintk)*gaussCoord
c
c shape functions
dN(1) = (one - g)*(one - h)*(one - r)/eight
dN(2) = (one + g)*(one - h)*(one - r)/eight
dN(3) = (one + g)*(one + h)*(one - r)/eight
dN(4) = (one - g)*(one + h)*(one - r)/eight
dN(5) = (one - g)*(one - h)*(one + r)/eight
dN(6) = (one + g)*(one - h)*(one + r)/eight
dN(7) = (one + g)*(one + h)*(one + r)/eight
dN(8) = (one - g)*(one + h)*(one + r)/eight
c
c derivative d(Ni)/d(g)
dNdz(1,1) = -(one - h)*(one - r)/eight
dNdz(1,2) = (one - h)*(one - r)/eight
dNdz(1,3) = (one + h)*(one - r)/eight
dNdz(1,4) = -(one + h)*(one - r)/eight
dNdz(1,5) = -(one - h)*(one + r)/eight
dNdz(1,6) = (one - h)*(one + r)/eight
dNdz(1,7) = (one + h)*(one + r)/eight
dNdz(1,8) = -(one + h)*(one + r)/eight
c
c derivative d(Ni)/d(h)
dNdz(2,1) = -(one - g)*(one - r)/eight
dNdz(2,2) = -(one + g)*(one - r)/eight
dNdz(2,3) = (one + g)*(one - r)/eight
dNdz(2,4) = (one - g)*(one - r)/eight
dNdz(2,5) = -(one - g)*(one + r)/eight
dNdz(2,6) = -(one + g)*(one + r)/eight
dNdz(2,7) = (one + g)*(one + r)/eight
dNdz(2,8) = (one - g)*(one + r)/eight
c
c derivative d(Ni)/d(r)
dNdz(3,1) = -(one - g)*(one - h)/eight
dNdz(3,2) = -(one + g)*(one - h)/eight
dNdz(3,3) = -(one + g)*(one + h)/eight
dNdz(3,4) = -(one - g)*(one + h)/eight
dNdz(3,5) = (one - g)*(one - h)/eight
dNdz(3,6) = (one + g)*(one - h)/eight
dNdz(3,7) = (one + g)*(one + h)/eight
dNdz(3,8) = (one - g)*(one + h)/eight
C
C 2D 4-nodes
C
else if (iCode.eq.i2d4node) then
c
c determine (g,h)
c
g = coord24(1,kintk)*gaussCoord
h = coord24(2,kintk)*gaussCoord
c
c shape functions
dN(1) = (one - g)*(one - h)/four;
dN(2) = (one + g)*(one - h)/four;
dN(3) = (one + g)*(one + h)/four;
dN(4) = (one - g)*(one + h)/four;
c
c derivative d(Ni)/d(g)
dNdz(1,1) = -(one - h)/four;
dNdz(1,2) = (one - h)/four;
dNdz(1,3) = (one + h)/four;
dNdz(1,4) = -(one + h)/four;
c
c derivative d(Ni)/d(h)
dNdz(2,1) = -(one - g)/four;
dNdz(2,2) = -(one + g)/four;
dNdz(2,3) = (one + g)/four;
dNdz(2,4) = (one - g)/four;
end if
c
return
end
c*****************************************************************
c Get local predefined fileds
c
subroutine tempfv(kintk,ninpt,nnode,ndim,shape,predef,
* npredf,predef_loc,dpredef_loc)
c
include 'aba_param.inc'
c
dimension shape(nnode),predef(2,npredf,nnode)
dimension predef_loc(npredf),dpredef_loc(npredf)
parameter (zero=0.d0)
c
do k1=1,npredf
predef_loc(k1) = zero
dpredef_loc(k1) = zero
do k2=1,nnode
predef_loc(k1) = predef_loc(k1)+
& (predef(1,k1,k2)-predef(2,k1,k2))*shape(k2)
dpredef_loc(k1) = dpredef_loc(k1)+predef(2,k1,k2)*shape(k2)
end do
end do
c
return
end
c*****************************************************************
c Compute jacobian matrix
c
subroutine jacobian(jelem,mcrd,ndim,nnode,
1 coords,dshape,djac,xjaci,pnewdt,coords_new,xjaci_new,
2 djac_new)
c
c Notation: ndim ....... element dimension
c nnode ..... number of nodes
c coords ..... coordinates of nodes
c dshape ..... derivs of shape fcn
c djac ....... determinant of Jacobian
c xjaci ...... inverse of Jacobian matrix
c
c
include 'aba_param.inc'
parameter(zero=0.d0, fourth=0.25d0, maxDof=3)
dimension xjac(maxDof,maxDof), xjaci(ndim,*), coords(mcrd,*)
dimension dshape(ndim,*),coords_new(mcrd,*)
dimension xjac_new(maxDof,maxDof), xjaci_new(ndim,*)
c
do i = 1, ndim
do j = 1, ndim
xjac(i,j) = zero
xjaci(i,j) = zero
xjac_new(i,j) = zero
xjaci_new(i,j) = zero
end do
end do
c
do inod= 1, nnode
do idim = 1, ndim
do jdim = 1, ndim
xjac(idim,jdim) = xjac(idim,jdim) +
1 dshape(jdim,inod)*coords(idim,inod)
end do
end do
end do
C
C ndim == 3
C
if (ndim.eq.3) then
djac = xjac(1,1)*xjac(2,2)*xjac(3,3) +
& xjac(2,1)*xjac(3,2)*xjac(1,3) +
& xjac(3,1)*xjac(2,3)*xjac(1,2) -
& xjac(3,1)*xjac(2,2)*xjac(1,3) -
& xjac(2,1)*xjac(1,2)*xjac(3,3) -
& xjac(1,1)*xjac(2,3)*xjac(3,2)
if (djac .gt. zero) then
! jacobian is positive - o.k.
xjaci(1,1) = (xjac(2,2)*xjac(3,3)-xjac(2,3)*xjac(3,2))/djac
xjaci(1,2) = (xjac(1,3)*xjac(3,2)-xjac(1,2)*xjac(3,3))/djac
xjaci(1,3) = (xjac(1,2)*xjac(2,3)-xjac(1,3)*xjac(2,2))/djac
!
xjaci(2,1) = (xjac(2,3)*xjac(3,1)-xjac(2,1)*xjac(3,3))/djac
xjaci(2,2) = (xjac(1,1)*xjac(3,3)-xjac(1,3)*xjac(3,1))/djac
xjaci(2,3) = (xjac(1,3)*xjac(2,1)-xjac(1,1)*xjac(2,3))/djac
!
xjaci(3,1) = (xjac(2,1)*xjac(3,2)-xjac(2,2)*xjac(3,1))/djac
xjaci(3,2) = (xjac(1,2)*xjac(3,1)-xjac(1,1)*xjac(3,2))/djac
xjaci(3,3) = (xjac(1,1)*xjac(2,2)-xjac(1,2)*xjac(2,1))/djac
else
! negative or zero jacobian
write(7,*)'WARNING: element',jelem,'has neg.
1 Jacobian'
pnewdt = fourth
endif
C
C ndim == 2
C
else if (ndim.eq.2) then
djac = xjac(1,1)*xjac(2,2) - xjac(1,2)*xjac(2,1)
djac_new = xjac_new(1,1)*xjac_new(2,2)
* - xjac_new(1,2)*xjac_new(2,1)
if (djac .gt. zero) then
! jacobian is positive - o.k.
xjaci(1,1) = xjac(2,2)/djac
xjaci(2,2) = xjac(1,1)/djac
xjaci(1,2) = -xjac(1,2)/djac
xjaci(2,1) = -xjac(2,1)/djac
else
! negative or zero jacobian
write(7,*)'WARNING: element',jelem,'has neg.
1 Jacobian'
pnewdt = fourth
endif
end if
return
end
c*****************************************************************
c
c Compute the B matrix
c
subroutine bmatrix(xjaci,dshape,nnode,ndim,bmat,
* xjaci_new,bmat_new)
c
c Notation:
c bmat(i) .....dN1/dx, dN1/dy, dN2/dx, dN2/dy..
c xjaci ...... inverse Jabobian matrix
c dshape ......derivative of shape functions
c
include 'aba_param.inc'
c
parameter (zero=0.d0)
dimension bmat(*), dshape(ndim,*)
dimension xjaci(ndim,*)
dimension xjaci_new(ndim,*),bmat_new(*)
do i = 1, nnode*ndim
bmat(i) = zero
bmat_new(i) = zero
end do
do inod = 1, nnode
do ider = 1, ndim
do idim = 1, ndim
irow = idim + (inod - 1)*ndim
bmat(irow) = bmat(irow) +
1 xjaci(idim,ider)*dshape(ider,inod)
end do
end do
end do
return
end
c*****************************************************************
c
c Set temperatures
c
subroutine settemp(ndofel,ndof,ndim,nnode,
1 mlvarx,bmat,du,dstran,u,xx1,xx1Old,temp,dtemp,dtemdx,dN)
c
c
c
include 'aba_param.inc'
parameter(zero=0.d0, one=1.d0)
dimension dstran(*), bmat(ndim,*),
1 du(mlvarx, *), xdu(3), xx1(3,*),
2 u(ndofel), utmp(3),
3 utmpOld(3),xx1Old(3,*),eps(3,3),dInvFold(3,3)
dimension dtemdx(*),dN(*)
C
c
c****************************************************************
c Compute temp, dtemp, and temp gradient at the material point
c****************************************************************
c
temp = zero
dtemp = zero
do iNode=1, nnode
temp = temp + dN(iNode)*u(iNode)
dtemp = dtemp + dN(iNode)*du(iNode,1)
end do
do iDof = 1, ndim
dtemdx(iDof) = zero
do iNode=1, nnode
dtemdx(iDof) = dtemdx(iDof) + bmat(idof,iNode)*u(iNode)
end do
end do
c
return
end
c*****************************************************************
c
c Compute element jacobian and nodal forces
c
subroutine rhsjacobian(nnode,ndim,ndof,
1 weight,djac,rhoUdot,rhoUdotdt,rhoUdotdg,flux,dfdt,
2 dfdg,dN,bmat,stiff,force,dtime,lflags)
c
c Stiffness matrix and internal force contributions at
c material integration point
c
include 'aba_param.inc'
parameter(zero=0.d0,maxDof=3)
dimension stiff(ndof*nnode,*)
dimension force(*)
dimension flux(*),dfdt(*),dfdg(ndim,*),rhoUdotdg(*)
dimension dN(*),bmat(ndim,*),lflags(*)
do i = 1, ndof*nnode
force(i) = zero
do j = 1, ndof*nnode
stiff(j,i) = zero
end do
end do
dvol=weight*djac
do nodj=1, nnode
if (lflags(1).eq.32.or.lflags(1).eq.33)
& force(nodj) = dN(nodj)*rhoUdot*dvol
ccc force(nodj) = dN(nodj)*(rhoUdot-rpl)*dvol
do jDof=1, ndim
force(nodj) = force(nodj)+bmat(jDof,nodj)*flux(jDof)*dvol
do nodi=1, nnode
ccc stiff(nodj,nodi) = stiff(nodj,nodi) +
ccc * bmat(jDof,nodj)*dN(nodi)*dfdt(jDof)*dvol
do iDof=1, ndim
stiff(nodj,nodi) = stiff(nodj,nodi) +
* bmat(jDof,nodj)*bmat(iDof,nodi)*dfdg(jDof,iDof)*dvol
end do
end do
end do
end do
do nodj=1, nnode
do nodi=1, nnode
do iDof=1, ndim
ccc stiff(nodj,nodi) = stiff(nodj,nodi) +
ccc * dN(nodj)*bmat(iDof,nodi)*rhoUdotdg(iDof)*dvol
end do
end do
end do
c
if (lflags(1).eq.32.or.lflags(1).eq.33) then
do nodj=1, nnode
do nodi=1, nnode
stiff(nodj,nodi) = stiff(nodj,nodi) +
* rhoUdotdt*dN(nodj)*dN(nodi)*dvol/dtime
end do
end do
end if
c
return
end

View file

@ -0,0 +1,108 @@
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),dndg(4),dndh(4),
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 gx(4),hx(4),gwei(4),dN(4),phix(8),phiy(8)
c
parameter(zero=0.d0,one=1.d0)
C MATERIAL PROPERTY DEFINITION
thick = 1.
rho = 1.
spec = 1.
conduc = 1.
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
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 i=1,4
gwei(i)=1.
enddo
c assemble amatrx and rhs
do k=1,4
c loop through gauss pts
g=gx(k)
h=hx(k)
c shape functions
dN(1) = (one - g)*(one - h)/4.
dN(2) = (one + g)*(one - h)/4.
dN(3) = (one + g)*(one + h)/4.
dN(4) = (one - g)*(one + h)/4.
c derivative d(Ni)/d(g)
dNdg(1) = -(one - h)/4.
dNdg(2) = (one - h)/4.
dNdg(3) = (one + h)/4.
dNdg(4) = -(one + h)/4.
c derivative d(Ni)/d(h)
dNdh(1) = -(one - g)/4.
dNdh(2) = -(one + g)/4.
dNdh(3) = (one + g)/4.
dNdh(4) = (one - g)/4.
c derivative dx/dg,dx/dh,dy/dg,dy/dh
dxdg=zero
dxdh=zero
dydg=zero
dydh=zero
do i=1,4
dxdg=dxdg+coords(1,i)*dNdg(i)
dxdh=dxdh+coords(1,i)*dNdh(i)
dydg=dydg+coords(2,i)*dNdg(i)
dydh=dydh+coords(2,i)*dNdh(i)
enddo
c calculation of jacobian
ajacob=(dxdg*dydh-dxdh*dydg)
c derivative dn/dx,dn/dy
do i=1,4
phix(i)=(dNdg(i)*dydh-dNdh(i)*dydg)/ajacob
phiy(i)=(dNdh(i)*dxdg-dNdg(i)*dxdh)/ajacob
enddo
dtdx=zero
dtdy=zero
t =zero
told=zero
do i=1,4
dtdx=u(i)*phix(i)+dtdx
dtdy=u(i)*phiy(i)+dtdy
t=u(i)*dn(i)+t
told=(u(i)-du(i,nrhs))*dn(i)+told
end do
cond=1.
dcdt=zero
dtdt=(t-told)/dtime
we=gwei(k)*ajacob
do ki=1,4
c loop over nodes
rhs(ki,nrhs) = rhs(ki,nrhs) -
1 we*(dN(ki)*rho*spec*dtdt +
2 cond*(phix(ki)*dtdx + phiy(ki)*dtdy))
do kj=1,4
amatrx(ki,kj)= amatrx(ki,kj) +
1 we*(dn(ki)*dn(kj)*rho*spec/dtime +
1 cond*(phix(ki)*phix(kj) + phiy(ki)*phiy(kj)))
end do
end do
enddo
end if
return
end

View file

@ -0,0 +1,260 @@
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),dndg(4),dndh(4)
dimension theta(4),rjac(2,2),rjaci(2,2)
dimension gx(100,4),hx(100,4),xi(2),yi(2),gi(2),hi(2)
dimension c(2),gp(2,8),gm2(8,8)
c
parameter(zero=0.d0,one=1.d0)
c material property definition
thick = 1.
rho = 1.
beta=0.
dpos=0.6
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
c if (sign(1.,theta(1))/=sign(1.,theta(2)))then
if (2==1)then
c possible enriched element
npart=10
rpart=float(npart)
ienr=npart*npart
do isdx=1,npart
do isdy=1,npart
rmidx=-1.-1./rpart+(2./rpart)*float(isdx)
rmidy=-1.-1./rpart+(2./rpart)*float(isdy)
isubindex=npart*(isdy-1)+isdx
gpos=1./(sqrt(3.)*rpart)
gx(isubindex,1)=rmidx-gpos
gx(isubindex,2)=rmidx+gpos
gx(isubindex,3)=rmidx+gpos
gx(isubindex,4)=rmidx-gpos
hx(isubindex,1)=rmidy-gpos
hx(isubindex,2)=rmidy-gpos
hx(isubindex,3)=rmidy+gpos
hx(isubindex,4)=rmidy+gpos
enddo
enddo
c check if int points are on different sides of front
icheck=0
do i=1,ienr
do 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)
rLS=theta(1)*phi(1)+theta(2)*phi(3)
1 +theta(3)*phi(5)+theta(4)*phi(7)
if (i==1 .and. j==1)then
sgn=sign(1.,rLS)
else
if (sign(1.,rLS)/=sgn)then
icheck=1
endif
endif
enddo
enddo
if (icheck==0)then
c regular element - fix extra dofs
ienr=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
endif
else
c Normal Shp Funs
ienr=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
endif
c assemble amatrx and rhs
do i=1,ienr
do 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)
rLS=theta(1)*phi(1)+theta(2)*phi(3)
1 +theta(3)*phi(5)+theta(4)*phi(7)
cond=1.
spec=1.
do iter=1,4
phi(2*iter)=phi(2*iter-1)*
1 (abs(rLS)-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.,rLS)*(phig(1)*theta(1)+phig(3)*
1 theta(2)+phig(5)*theta(3)+phig(7)*theta(4))
diLSh=sign(1.,rLS)*(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(rLS)-
1 abs(theta(iter)))+phi(2*iter-1)*diLSg
phih(2*iter)=phih(2*iter-1)*(abs(rLS)-
1 abs(theta(iter)))+phi(2*iter-1)*diLSh
enddo
rjac=zero
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)+
1 rjaci(1,2)*phih(iter)
phiy(iter)=rjaci(2,1)*phig(iter)+
1 rjaci(2,2)*phih(iter)
enddo
dtdx=zero
dtdy=zero
t =zero
told=zero
do iter=1,8
dtdx=u(iter)*phix(iter)+dtdx
dtdy=u(iter)*phiy(iter)+dtdy
t=u(iter)*phi(iter)+t
told=(u(iter)-du(iter,nrhs))*phi(iter)+told
end do
dtdt=(t-told)/dtime
we=djac
do ki=1,8
c loop over nodes
rhs(ki,nrhs) = rhs(ki,nrhs) -
1 (we/float(ienr))*(phi(ki)*rho*spec*dtdt+
2 cond*(phix(ki)*dtdx + phiy(ki)*dtdy))
do kj=1,8
amatrx(ki,kj)=amatrx(ki,kj)+(we/float(ienr))
1 *(phi(ki)*phi(kj)*rho*spec/dtime+cond
2 *(phix(ki)*phix(kj)+phiy(ki)*phiy(kj)))
end do
end do
enddo
enddo
c if interface is in the element a penalty term is needed
if(ienr>1)then
icount=0
if (sign(1.,theta(1))/=sign(1.,theta(2)))then
icount=icount+1
f=abs(theta(1))/(abs(theta(1))+abs(theta(2)))
xi(icount)=f*(crdnx(2)-crdnx(1))+crdnx(1)
yi(icount)=f*(crdny(2)-crdny(1))+crdny(1)
gi(icount)=(2.*xi(icount)-(crdnx(1)+crdnx(2)))
1 /(-crdnx(1)+crdnx(2))
hi(icount)=-1.
endif
if (sign(1.,theta(2))/=sign(1.,theta(3)))then
icount=icount+1
f=abs(theta(2))/(abs(theta(2))+abs(theta(3)))
xi(icount)=f*(crdnx(3)-crdnx(2))+crdnx(2)
yi(icount)=f*(crdny(3)-crdny(2))+crdny(2)
gi(icount)=1.
hi(icount)=(2.*yi(icount)-(crdny(2)+crdny(3)))
1 /(-crdny(2)+crdny(3))
endif
if (sign(1.,theta(3))/=sign(1.,theta(4)))then
icount=icount+1
f=abs(theta(3))/(abs(theta(3))+abs(theta(4)))
xi(icount)=f*(crdnx(4)-crdnx(3))+crdnx(3)
yi(icount)=f*(crdny(4)-crdny(3))+crdny(3)
gi(icount)=(2.*xi(icount)-(crdnx(4)+crdnx(3)))
1 /(-crdnx(4)+crdnx(3))
hi(icount)=1.
endif
if (sign(1.,theta(1))/=sign(1.,theta(4)))then
icount=icount+1
f=abs(theta(1))/(abs(theta(1))+abs(theta(4)))
xi(icount)=f*(crdnx(4)-crdnx(1))+crdnx(1)
yi(icount)=f*(crdny(4)-crdny(1))+crdny(1)
gi(icount)=-1.
hi(icount)=(2.*yi(icount)-(crdny(1)+crdny(4)))
1 /(-crdny(4)+crdny(1))
endif
c(1)=1.
c(2)=1.
do iter=1,2
Gp(iter,1)=0.25*(1.-gi(iter))*(1.-hi(iter))
Gp(iter,3)=0.25*(1.+gi(iter))*(1.-hi(iter))
Gp(iter,5)=0.25*(1.+gi(iter))*(1.+hi(iter))
Gp(iter,7)=0.25*(1.-gi(iter))*(1.+hi(iter))
Gp(iter,2)=-Gp(iter,1)*abs(theta(1))
Gp(iter,4)=-Gp(iter,3)*abs(theta(2))
Gp(iter,6)=-Gp(iter,5)*abs(theta(3))
Gp(iter,8)=-Gp(iter,7)*abs(theta(4))
enddo
do i=1,8
rhs(i,nrhs)=rhs(i,nrhs)+
1 beta*(Gp(1,i)*c(1)+Gp(2,i)*c(2))
enddo
c find GtG
gm2=0.
do i=1,8
do j=1,8
gm2(i,j)=gp(1,i)*gp(1,j)+gp(2,i)*gp(2,j)
enddo
enddo
c add penalty stiffness
do i=1,8
do j=1,8
amatrx(i,j)=amatrx(i,j)+beta*gm2(i,j)
enddo
enddo
endif
end if
return
end

View file

@ -0,0 +1,260 @@
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),dndg(4),dndh(4)
dimension theta(4),rjac(2,2),rjaci(2,2)
dimension gx(100,4),hx(100,4),xi(2),yi(2),gi(2),hi(2)
dimension c(2),gp(2,8),gm2(8,8)
c
parameter(zero=0.d0,one=1.d0)
c material property definition
thick = 1.
rho = 1.
beta=0.
dpos=0.6
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
c if (sign(1.,theta(1))/=sign(1.,theta(2)))then
if (2==1)then
c possible enriched element
npart=10
rpart=float(npart)
ienr=npart*npart
do isdx=1,npart
do isdy=1,npart
rmidx=-1.-1./rpart+(2./rpart)*float(isdx)
rmidy=-1.-1./rpart+(2./rpart)*float(isdy)
isubindex=npart*(isdy-1)+isdx
gpos=1./(sqrt(3.)*rpart)
gx(isubindex,1)=rmidx-gpos
gx(isubindex,2)=rmidx+gpos
gx(isubindex,3)=rmidx+gpos
gx(isubindex,4)=rmidx-gpos
hx(isubindex,1)=rmidy-gpos
hx(isubindex,2)=rmidy-gpos
hx(isubindex,3)=rmidy+gpos
hx(isubindex,4)=rmidy+gpos
enddo
enddo
c check if int points are on different sides of front
icheck=0
do i=1,ienr
do 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)
rLS=theta(1)*phi(1)+theta(2)*phi(3)
1 +theta(3)*phi(5)+theta(4)*phi(7)
if (i==1 .and. j==1)then
sgn=sign(1.,rLS)
else
if (sign(1.,rLS)/=sgn)then
icheck=1
endif
endif
enddo
enddo
if (check==0)then
c regular element - fix extra dofs
ienr=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
endif
else
c Normal Shp Funs
ienr=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
endif
c assemble amatrx and rhs
do i=1,ienr
do 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)
rLS=theta(1)*phi(1)+theta(2)*phi(3)
1 +theta(3)*phi(5)+theta(4)*phi(7)
cond=1.
spec=1.
do iter=1,4
phi(2*iter)=phi(2*iter-1)*
1 (abs(rLS)-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.,rLS)*(phig(1)*theta(1)+phig(3)*
1 theta(2)+phig(5)*theta(3)+phig(7)*theta(4))
diLSh=sign(1.,rLS)*(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(rLS)-
1 abs(theta(iter)))+phi(2*iter-1)*diLSg
phih(2*iter)=phih(2*iter-1)*(abs(rLS)-
1 abs(theta(iter)))+phi(2*iter-1)*diLSh
enddo
rjac=zero
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)+
1 rjaci(1,2)*phih(iter)
phiy(iter)=rjaci(2,1)*phig(iter)+
1 rjaci(2,2)*phih(iter)
enddo
dtdx=zero
dtdy=zero
t =zero
told=zero
do iter=1,8
dtdx=u(iter)*phix(iter)+dtdx
dtdy=u(iter)*phiy(iter)+dtdy
t=u(iter)*phi(iter)+t
told=(u(iter)-du(iter,nrhs))*phi(iter)+told
end do
dtdt=(t-told)/dtime
we=djac
do ki=1,8
c loop over nodes
rhs(ki,nrhs) = rhs(ki,nrhs) -
1 (we/float(ienr))*(phi(ki)*rho*spec*dtdt+
2 cond*(phix(ki)*dtdx + phiy(ki)*dtdy))
do kj=1,8
amatrx(ki,kj)=amatrx(ki,kj)+(we/float(ienr))
1 *(phi(ki)*phi(kj)*rho*spec/dtime+cond
2 *(phix(ki)*phix(kj)+phiy(ki)*phiy(kj)))
end do
end do
enddo
enddo
c if interface is in the element a penalty term is needed
if(ienr>1)then
icount=0
if (sign(1.,theta(1))/=sign(1.,theta(2)))then
icount=icount+1
f=abs(theta(1))/(abs(theta(1))+abs(theta(2)))
xi(icount)=f*(crdnx(2)-crdnx(1))+crdnx(1)
yi(icount)=f*(crdny(2)-crdny(1))+crdny(1)
gi(icount)=(2.*xi(icount)-(crdnx(1)+crdnx(2)))
1 /(-crdnx(1)+crdnx(2))
hi(icount)=-1.
endif
if (sign(1.,theta(2))/=sign(1.,theta(3)))then
icount=icount+1
f=abs(theta(2))/(abs(theta(2))+abs(theta(3)))
xi(icount)=f*(crdnx(3)-crdnx(2))+crdnx(2)
yi(icount)=f*(crdny(3)-crdny(2))+crdny(2)
gi(icount)=1.
hi(icount)=(2.*yi(icount)-(crdny(2)+crdny(3)))
1 /(-crdny(2)+crdny(3))
endif
if (sign(1.,theta(3))/=sign(1.,theta(4)))then
icount=icount+1
f=abs(theta(3))/(abs(theta(3))+abs(theta(4)))
xi(icount)=f*(crdnx(4)-crdnx(3))+crdnx(3)
yi(icount)=f*(crdny(4)-crdny(3))+crdny(3)
gi(icount)=(2.*xi(icount)-(crdnx(4)+crdnx(3)))
1 /(-crdnx(4)+crdnx(3))
hi(icount)=1.
endif
if (sign(1.,theta(1))/=sign(1.,theta(4)))then
icount=icount+1
f=abs(theta(1))/(abs(theta(1))+abs(theta(4)))
xi(icount)=f*(crdnx(4)-crdnx(1))+crdnx(1)
yi(icount)=f*(crdny(4)-crdny(1))+crdny(1)
gi(icount)=-1.
hi(icount)=(2.*yi(icount)-(crdny(1)+crdny(4)))
1 /(-crdny(4)+crdny(1))
endif
c(1)=1.
c(2)=1.
do iter=1,2
Gp(iter,1)=0.25*(1.-gi(iter))*(1.-hi(iter))
Gp(iter,3)=0.25*(1.+gi(iter))*(1.-hi(iter))
Gp(iter,5)=0.25*(1.+gi(iter))*(1.+hi(iter))
Gp(iter,7)=0.25*(1.-gi(iter))*(1.+hi(iter))
Gp(iter,2)=-Gp(iter,1)*abs(theta(1))
Gp(iter,4)=-Gp(iter,3)*abs(theta(2))
Gp(iter,6)=-Gp(iter,5)*abs(theta(3))
Gp(iter,8)=-Gp(iter,7)*abs(theta(4))
enddo
do i=1,8
rhs(i,nrhs)=rhs(i,nrhs)+
1 beta*(Gp(1,i)*c(1)+Gp(2,i)*c(2))
enddo
c find GtG
gm2=0.
do i=1,8
do j=1,8
gm2(i,j)=gp(1,i)*gp(1,j)+gp(2,i)*gp(2,j)
enddo
enddo
c add penalty stiffness
do i=1,8
do j=1,8
amatrx(i,j)=amatrx(i,j)+beta*gm2(i,j)
enddo
enddo
endif
end if
return
end

View file

@ -0,0 +1,113 @@
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),dndg(4),dndh(4)
dimension theta(4),rjac(2,2),rjaci(2,2)
dimension gx(100,4),hx(100,4),xi(2),yi(2),gi(2),hi(2)
dimension c(2),gp(2,8),gm2(8,8)
c
parameter(zero=0.d0,one=1.d0)
c material property definition
thick = 1.
rho = 1.
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)
enddo
c Normal Shp Funs
ienr=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
c assemble amatrx and rhs
do i=1,ienr
do j=1,4
g=gx(i,j)
h=hx(i,j)
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=zero
do 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)
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,4
phix(iter)=rjaci(1,1)*phig(iter)+
1 rjaci(1,2)*phih(iter)
phiy(iter)=rjaci(2,1)*phig(iter)+
1 rjaci(2,2)*phih(iter)
enddo
dtdx=zero
dtdy=zero
t =zero
told=zero
do iter=1,4
dtdx=u(iter)*phix(iter)+dtdx
dtdy=u(iter)*phiy(iter)+dtdy
t=u(iter)*phi(iter)+t
told=(u(iter)-du(iter,nrhs))*phi(iter)+told
end do
dtdt=(t-told)/dtime
we=djac
do ki=1,4
c loop over nodes
rhs(ki,nrhs) = rhs(ki,nrhs) -
1 (we/float(ienr))*(phi(ki)*rho*spec*dtdt+
2 cond*(phix(ki)*dtdx + phiy(ki)*dtdy))
do kj=1,4
amatrx(ki,kj)=amatrx(ki,kj)+(we/float(ienr))
1 *(phi(ki)*phi(kj)*rho*spec/dtime+cond
2 *(phix(ki)*phix(kj)+phiy(ki)*phiy(kj)))
end do
end do
enddo
enddo
end if
return
end

View file

@ -0,0 +1,84 @@
*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, 0.25, 0., 0.
3, 0.5, 0., 0.
4, 0.75, 0., 0.
5, 1., 0., 0.
6, 0., 0.25, 0.
7, 0.25, 0.25, 0.
8, 0.5, 0.25, 0.
9, 0.75, 0.25, 0.
10, 1., 0.25, 0.
*USER ELEMENT,NODES=4,TYPE=U1,PROP=1,COORDINATES=2,VAR=2,unsymm
11,
*Element, type=U1,ELSET=UEL
1, 1, 2,7,6
2, 2, 3,8,7
3, 3, 4,9,8
4, 4, 5,10,9
*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,2,3,6,7,8
*Nset, nset=_PickedSet17, internal, instance=Part-1-1
4,5,9,10
*Nset, nset=Set-6, instance=Part-1-1
1,6
*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.01, 0.1, 1e-09, 0.01,
**
** 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,79 @@
*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, 0.25, 0., 0.
3, 0.5, 0., 0.
4, 0.75, 0., 0.
5, 1., 0., 0.
*USER ELEMENT,NODES=2,TYPE=U1,PROP=1,COORDINATES=1,VAR=2,unsymm
11,12
*Element, type=U1,ELSET=UEL
1, 1, 2,
2, 2, 3,
3, 3,4
4, 4,5
*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,2,3
*Nset, nset=_PickedSet17, internal, instance=Part-1-1
4,5,6
*Nset, nset=Set-6, instance=Part-1-1
1,
*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.01, 0.1, 1e-09, 0.01,
**
** 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,237 @@
c***********************************************************
subroutine uelmat(rhs,amatrx,svars,energy,ndofel,nrhs,
1 nsvars,props,nprops,coords,mcrd,nnode,u,du,
2 v,a,jtype,time,dtime,kstep,kinc,jelem,params,
3 ndload,jdltyp,adlmag,predef,npredf,lflags,mlvarx,
4 ddlmag,mdload,pnewdt,jprops,njpro,period,
5 materiallib)
c
include 'aba_param.inc'
C
dimension rhs(mlvarx,*), amatrx(ndofel, ndofel), props(*),
1 svars(*), energy(*), coords(mcrd, nnode), u(ndofel),
2 du(mlvarx,*), v(ndofel), a(ndofel), time(2), params(*),
3 jdltyp(mdload,*), adlmag(mdload,*), ddlmag(mdload,*),
4 predef(2, npredf, nnode), lflags(*), jprops(*)
parameter (zero=0.d0, dmone=-1.0d0, one=1.d0, four=4.0d0,
1 fourth=0.25d0,gaussCoord=0.577350269d0)
parameter (ndim=2, ndof=2, nshr=1,nnodemax=4,
1 ntens=4, ninpt=4, nsvint=4)
c
dimension stiff(ndof*nnodemax,ndof*nnodemax),
1 force(ndof*nnodemax), shape(nnodemax), dshape(ndim,nnodemax),
2 xjac(ndim,ndim),xjaci(ndim,ndim), bmat(nnodemax*ndim),
3 statevLocal(nsvint),stress(ntens), ddsdde(ntens, ntens),
4 stran(ntens), dstran(ntens), wght(ninpt)
c
dimension predef_loc(npredf),dpredef_loc(npredf),
1 defGrad(3,3),utmp(3),xdu(3),stiff_p(3,3),force_p(3)
dimension coord24(2,4),coords_ip(3)
data coord24 /dmone, dmone,
2 one, dmone,
3 one, one,
4 dmone, one/
c
data wght /one, one, one, one/
c*************************************************************
c U1 = first-order, plane strain, full integration
c*************************************************************
c define mass matrix as identity at start of analysis
if (lflags(3).eq.4) then
amatrx = zero
do i=1, ndofel
amatrx(i,i) = one
end do
goto 999
end if
c properties
thickness = 0.1d0
c initialize rhs and k
rhs = zero
amatrx = zero
c loop over integration points
do kintk = 1, ninpt
c determine gauss point in local sys (g,h)
c takes form: [4 3]
c [1 2]
g = coord24(1,kintk)*gaussCoord
h = coord24(2,kintk)*gaussCoord
c shape functions
shape(1) = (one - g)*(one - h)/four
shape(2) = (one + g)*(one - h)/four
shape(3) = (one + g)*(one + h)/four
shape(4) = (one - g)*(one + h)/four
c derivative d(Ni)/d(g)
dshape(1,1) = -(one - h)/four
dshape(1,2) = (one - h)/four
dshape(1,3) = (one + h)/four
dshape(1,4) = -(one + h)/four
c derivative d(Ni)/d(h)
dshape(2,1) = -(one - g)/four
dshape(2,2) = -(one + g)/four
dshape(2,3) = (one + g)/four
dshape(2,4) = (one - g)/four
c compute global coordinates of the ip
coords_ip = zero
do k1=1,nnode
do k2=1,mcrd
coords_ip(k2)=coords_ip(k2)+shape(k1)*coords(k2,k1)
end do
end do
c form b-matrix
djac = one
xjac = zero
xjaci = zero
c Get Jacobian
do inod= 1, nnode
do idim = 1, ndim
do jdim = 1, ndim
xjac(jdim,idim) = xjac(jdim,idim) +
1 dshape(jdim,inod)*coords(idim,inod)
end do
end do
end do
c Get Det of Jacobian
djac = xjac(1,1)*xjac(2,2) - xjac(1,2)*xjac(2,1)
if (djac .gt. zero) then
! jacobian is positive - invert it
xjaci(1,1) = xjac(2,2)/djac
xjaci(2,2) = xjac(1,1)/djac
xjaci(1,2) = -xjac(1,2)/djac
xjaci(2,1) = -xjac(2,1)/djac
else
! negative or zero jacobian - reduce time inc.
write(7,*)'WARNING: element',jelem,'has neg. Jacobian'
pnewdt = fourth
endif
if (pnewdt .lt. pnewdtLocal) pnewdtLocal = pnewdt
c Build B matrix
bmat = zero
do inod = 1, nnode
do ider = 1, ndim
do idim = 1, ndim
irow = idim + (inod - 1)*ndim
bmat(irow) = bmat(irow) +
1 xjaci(idim,ider)*dshape(ider,inod)
end do
end do
end do
c get strain inc
dstran(i) = zero
c set deformation gradient to Identity matrix
defGrad = zero
do k1=1,3
defGrad(k1,k1) = one
end do
c compute incremental strains
do nodi = 1, nnode
incr_row = (nodi - 1)*ndof
do i = 1, ndof
xdu(i)= du(i + incr_row,1)
utmp(i) = u(i + incr_row)
end do
dNidx = bmat(1+(nodi-1)*ndim)
dNidy = bmat(2+(nodi-1)*ndim)
dstran(1) = dstran(1)+dNidx*xdu(1)
dstran(2) = dstran(2)+dNidy*xdu(2)
dstran(4) = dstran(4)+dNidy*xdu(1)+dNidx*xdu(2)
c deformation gradient (prob not required for umat)
defGrad(1,1) = defGrad(1,1) + dNidx*utmp(1)
defGrad(1,2) = defGrad(1,2) + dNidy*utmp(1)
defGrad(2,1) = defGrad(2,1) + dNidx*utmp(2)
defGrad(2,2) = defGrad(2,2) + dNidy*utmp(2)
end do
c call constitutive routine
isvinc= (kintk-1)*nsvint
c prepare arrays for entry into material routines
do i = 1, nsvint
statevLocal(i)=svars(i+isvinc)
end do
c state variables
do k1=1,ntens
stran(k1) = statevLocal(k1)
stress(k1) = zero
end do
do i=1, ntens
do j=1, ntens
ddsdde(i,j) = zero
end do
ddsdde(i,j) = one
enddo
c compute characteristic element length
celent = sqrt(djac*dble(ninpt))
dvmat = djac*thickness
c
dvdv0 = one
call material_lib_mech(materiallib,stress,ddsdde,
1 stran,dstran,kintk,dvdv0,dvmat,defGrad,
2 predef_loc,dpredef_loc,npredf,celent,coords_ip)
c
do k1=1,ntens
statevLocal(k1) = stran(k1) + dstran(k1)
end do
isvinc= (kintk-1)*nsvint
c update element state variables
do i = 1, nsvint
svars(i+isvinc)=statevLocal(i)
end do
c form stiffness matrix and internal force vector
dNjdx = zero
dNjdy = zero
force = zero
stiff = zero
dvol= wght(kintk)*djac
do nodj = 1, nnode
incr_col = (nodj - 1)*ndof
dNjdx = bmat(1+(nodj-1)*ndim)
dNjdy = bmat(2+(nodj-1)*ndim)
force_p(1) = dNjdx*stress(1) + dNjdy*stress(4)
force_p(2) = dNjdy*stress(2) + dNjdx*stress(4)
do jdof = 1, ndof
jcol = jdof + incr_col
force(jcol) = force(jcol)+force_p(jdof)*dvol
end do
do nodi = 1, nnode
incr_row = (nodi -1)*ndof
dNidx = bmat(1+(nodi-1)*ndim)
dNidy = bmat(2+(nodi-1)*ndim)
stiff_p(1,1) = dNidx*ddsdde(1,1)*dNjdx
& + dNidy*ddsdde(4,4)*dNjdy
& + dNidx*ddsdde(1,4)*dNjdy
& + dNidy*ddsdde(4,1)*dNjdx
stiff_p(1,2) = dNidx*ddsdde(1,2)*dNjdy
& + dNidy*ddsdde(4,4)*dNjdx
& + dNidx*ddsdde(1,4)*dNjdx
& + dNidy*ddsdde(4,2)*dNjdy
stiff_p(2,1) = dNidy*ddsdde(2,1)*dNjdx
& + dNidx*ddsdde(4,4)*dNjdy
& + dNidy*ddsdde(2,4)*dNjdy
& + dNidx*ddsdde(4,1)*dNjdx
stiff_p(2,2) = dNidy*ddsdde(2,2)*dNjdy
& + dNidx*ddsdde(4,4)*dNjdx
& + dNidy*ddsdde(2,4)*dNjdx
& + dNidx*ddsdde(4,2)*dNjdy
do jdof = 1, ndof
icol = jdof + incr_col
do idof = 1, ndof
irow = idof + incr_row
stiff(irow,icol) = stiff(irow,icol) +
& stiff_p(idof,jdof)*dvol
end do
end do
end do
end do
c assemble rhs and lhs
do k1=1, ndof*nnode
rhs(k1, 1) = rhs(k1, 1) - force(k1)
do k2=1, ndof*nnode
amatrx(k1, k2) = amatrx(k1, k2) + stiff(k1,k2)
end do
end do
end do ! end loop on material integration points
pnewdt = pnewdtLocal
c
999 continue
c
return
end

View file

@ -0,0 +1,293 @@
c User subroutine UEL XFEM
subroutine uel(rhs,amatrx,svars,energy,ndofel,nrhs,nsvars,
1 props,nprops,coords,mcrd,nnode,u,du,v,a,jtype,time,dtime,
1 kstep,kinc,jelem,params,ndload,jdltyp,adlmag,predef,npredf,
1 lflags,mlvarx,ddlmag,mdload,pnewdt,jprops,njprop,period)
c
include 'aba_param.inc'
c ABAQUS defined variables:
dimension rhs(mlvarx,*), amatrx(ndofel,ndofel), props(*),
1 svars(nsvars), energy(8), coords(mcrd,nnode), u(ndofel),
1 du(mlvarx,*), v(ndofel), a(ndofel), time(2), params(*),
1 jdltyp(mdload,*), adlmag(mdload,*), ddlmag(mdload,*),
1 predef(2,npredf,nnode), lflags(*), jprops(*)
c
character*256 outdir
integer lenoutdir
integer i,j,k,pss,orderq(3),gint,flag,dimens
integer ncracks,maxncp,nelmx,nnodx,typexe(nnode),ix(nnode)
integer,parameter :: mpg=1650
integer,allocatable:: typex(:,:),ncp(:)
real*8 e, nu
real*8 f(ndofel)
real*8 sg(3,mpg),xypg(2,mpg),xe(8),ye(8),xyc0(2),xycprev(2)
real*8, allocatable:: xyc(:,:,:),dist(:,:),elemgg(:,:)
real*8, allocatable:: batg(:,:),dbatg(:,:),jatg(:)
c
c Read real and integer properties set at the ABAQUS input file
e = props(1)
nu = props(2)
pss = jprops(1)
orderq(1) = jprops(2)
orderq(2) = jprops(3)
orderq(3) = jprops(4)
dimens = jprops(5)
c Read the working directory
call getoutdir(outdir,lenoutdir)
c read number of cracks, max number of crack path points,
c number of enriched elements and enriched nodes.
open(68,file=outdir(1:lenoutdir)//\files\gginfox)
read(68,*) ncracks,maxncp,nelmx,nnodx
close(68)
c Allocate dimensions
allocate (typex(nnodx,2), ncp(ncracks))
allocate (xyc(ncracks,maxncp,2), dist(nnodx,3), elemgg(nelmx,10))
c read coordinates of path points for each crack
open(68,file=outdir(1:lenoutdir)//\files\ggxyc)
do i=1,ncracks
read(68,*) ncp(i)
do j=1,ncp(i)
read(68,*) (xyc(i,j,k),k=1,2)
end do
end do
close(68)
c Read list of enriched nodes, type of enrichment and distances
open(68,file=outdir(1:lenoutdir)//\files\ggnodex)
do i=1,nnodx
read(68,*) (typex(i,j),j=1,2),(dist(i,j),j=2,3)
dist(i,1)=typex(i,1)
end do
close(68)
c read list of enriched elements, type of enrichment and intersection points
open(68,file=outdir(1:lenoutdir)//\files\ggelemx)
do i=1,nelmx
read(68,*) (elemgg(i,j),j=1,10)
end do
close(68)
c call initializing routines for matrix and vectors
call initializem(rhs,ndofel,nrhs)
call initializem(amatrx,ndofel,ndofel)
call initializev(energy,8)
call initializev(svars,nsvars)
c verification of element type (type=12 for enriched element)
if (jtype.eq.12) then
c **************************************
c * 4 node enriched element with *
c * up to 12 dof/node for x-fem *
c **************************************
if (lflags(1).eq.71) then
c coupled thermal-stress, steady state analysis
if (lflags(3).eq.1) then
c Routine that defines the location of integration points according to
c the appropriate subdivision. This enables to know the total number of
c integration points for the current element, stored in gint, and whether
c the element is subdivided for integration (flag=1) or not.
CALL int2d_X(JELEM,NelmX,ElemGG,MCRD,NNODE,COORDS,orderQ,
1 NCracks,maxNCP,NCP,XYC,gint,sg,Xe,Ye,flag,mpg,xypg,
1 XYC0,XYCPrev)
c Allocate dimensions once the total number of integration points gint is known
allocate(batg(3*gint,ndofel),dbatg(3*gint,ndofel),jatg(gint))
call initializem(batg,3*gint,ndofel)
call initializem(dbatg,3*gint,ndofel)
call initializev(jatg,gint)
c Search of the enrichment type for the nodes of the current element.
c The keys to the enrichment types are stored in the element vector TypeXe
call typexelement(outdir,lenoutdir,jelem,nnode,nelmx,ix,typexe)
c element stiffness matrix computation, stored in amatrx
call k_u12(e,nu,amatrx,ndofel,nnode,dimens,mcrd,
coords,pss,nnodx,ix,typexe,dist,xyc0,xycprev,
gint,sg,xe,ye,flag,batg,dbatg,jatg)
c Routine that multiplies AMATRX times U to obtain the force vector F
c at the end of the current increment
call mult_v(amatrx,ndofel,ndofel,u,f,ndofel)
c compute the residual force vector
do i=1,ndofel
rhs(i,1) = rhs(i,1) - f(i)
end do
c Compute stresses at Gauss points for post-processing purposes
c Store them as SVARS for output to the results file (.fil)
call svars_u12(jtype,jelem,svars,nsvars,u,ndofel,batg,
1 dbatg,jatg,gint,mpg,xypg)
end if
end if
end if
return
end
C Element stiffness matrix. Subroutine: K U12
subroutine k_u12(e,nu,amatrx,ndofel,nnode,dimens,mcrd,
1 COORDS,PSS,NnodX,ix,TypeXe,Dist,XYC0,XYCPrev,
1 gint,sg,Xe,Ye,flag,BatG,DBatG,JatG)
implicit none
integer ndofel,nnode,dimens,mcrd,pss,nnodx,gint,flag,pos
integer l,i,j,kk,typexe(nnode),ix(nnode)
real*8 e,nu,dist(nnodx,3),sg(3,*)
real*8 amatrx(ndofel,ndofel),xyc0(2),xycprev(2)
real*8 xe(2*nnode),ye(2*nnode),coords(mcrd,nnode),xl(dimens,nnode)
real*8 xsj(gint),shp(3,4)
real*8 dnf(nnode,2,4),fnode(nnode,4),h,hnode(nnode)
real*8 b(3,ndofel), db(3,ndofel), bt(ndofel,3), d(3,3)
real*8 batg(3*gint,ndofel),dbatg(3*gint,ndofel),jatg(gint)
logical nodetype1,nodetype2
c NOTES:
c Routine shapef2D is called to compute standard shape functions,
c derivatives and jacobian at integration points. This routine outputs:
c shp(3,*) - Shape functions and derivatives at point
c shp(1,i) = dN_i/dx = dN_i/dx1
c shp(2,i) = dN_i/dy = dN_i/dx2
c shp(3,i) = N_i
c xsj - Jacobian determinant at point
c Local coordinates of integration points are passed in sg(1,*), sg(2,*)
c Integration weights are passed in sg(3,*)
c Initialize AMATRX and logical variables
call initializem(amatrx,ndofel,ndofel)
NodeType1=.false.
NodeType2=.false.
c Reduce info passed thru COORDS (3D) to xl (2D)
do i=1,dimens
do j=1,nnode
xl(i,j)=coords(i,j)
end do
end do
c Define constitutive stress-strain elastic matrix
call calc_d(pss,d,e,nu)
c Specify the type of nodal enrichment
do i=1,nnode
if (typexe(i).eq.1) then
nodetype1=.true.
elseif (typexe(i).eq.2) then
nodetype2=.true.
end if
end do
c Numerical integration loop over gint integration points
DO l = 1,gint
c Compute shape functions, derivatives and jacobian at integration point
call shapef2d(sg(1,l),xl,shp,xsj(l),dimens,nnode,ix,.false.)
if (flag.eq.1) then !element is subdivided for integration
xsj(l) = sg(3,l) !the integration weight includes the jacobian
else !element is not subdivided. standard integration
xsj(l) = xsj(l)*sg(3,l)
endif
c Value of the Heaviside function at integration point
c (This call is also used to store the values of H
c at nodes of the element for modified enrichment)
if (nodetype1) then
call heaviside(nnodx,dist,nnode,ix,shp,h,hnode)
endif
c Derivatives of shape functions Ni times enrichment functions Fj at integration point
c (This call is also used to compute the derivatives of shape functions Ni times
c enrichment functions Fj at nodes of the element for modified enrichment)
if (nodetype2) then
call fcracktip(xyc0,xycprev,shp,xe,ye,dnf,fnode)
endif
c STIFFNESS MATRIX COMPUTATION:
c Assembly of element matrix B (denoted as B) at integration point
call initializem(b,3,ndofel)
pos=1
c loop over nodes
do i= 1,nnode
c Contribution to B of derivatives of standard shape functions
B(1,Pos) = shp(1,i)
B(2,Pos+1)= shp(2,i)
B(3,Pos) = shp(2,i)
B(3,Pos+1)= shp(1,i)
c Contribution to B of derivatives of shape functions times Heaviside function
if (typexe(i).eq.1) then
b(1,2+pos) = shp(1,i)*(h-hnode(i))
b(2,3+pos) = shp(2,i)*(h-hnode(i))
b(3,2+pos) = shp(2,i)*(h-hnode(i))
b(3,3+pos) = shp(1,i)*(h-hnode(i))
c Contribution to B of derivatives of shape functions times crack tip functions
elseif(typexe(i).eq.2) then
do kk= 1,4
b(1,2*kk+2+pos)= dnf(i,1,kk)-shp(1,i)*fnode(i,kk)
b(2,2*kk+3+pos)= dnf(i,2,kk)-shp(2,i)*fnode(i,kk)
b(3,2*kk+2+pos)= dnf(i,2,kk)-shp(2,i)*fnode(i,kk)
b(3,2*kk+3+pos)= dnf(i,1,kk)-shp(1,i)*fnode(i,kk)
end do
end if
Pos=Pos+12 !Each node has 12 dof
end do ! i = end loop over element nodes
db=matmul(d,b) ! matrix d*b
bt=transpose(b) ! b transpose
c Integration of BT*D*B
amatrx= amatrx + matmul(bt,db)*xsj(l)
c store information at each integration point for further post-processing
do i=1,3
do j=1,ndofel
batg(3*(l-1)+i,j)=b(i,j)
dbatg(3*(l-1)+i,j)=db(i,j)
end do
end do
jatg(l)=xsj(l)
end do ! l = end loop for each integration point
return
end
c
SUBROUTINE SVARS_U12(JTYPE,JELEM,SVARS,NSVARS,U,Dof,BatG,DBatG,
* JatG,gint,mpg,xypg)
c Calculates and/or stores the following magnitudes at the element integration points,
c storing them in SVARS: strains, stresses, strain energy density, dv/dx, du/dy, jacobian,
c dNi/dx, dNi/dy, global coordinates of integration points.
IMPLICIT NONE
INTEGER i,j,k,NSVARS, Dof, gint, JTYPE,JELEM,mpg
REAL*8 SVARS(NSVARS), U(Dof),BatG(3*gint,Dof),DBatG(3*gint,Dof)
REAL*8 JatG(gint),B(3,Dof),DB(3,Dof),Bdvdx(3,Dof),Bdudy(3,Dof)
REAL*8 EPS(3),SIG(3),W,dvdx(3),dudy(3),JAC,xypg(2,mpg)
c &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
39
c &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
c First value stored in SVARS is the total number of integration points
c of the enriched element
SVARS(1)=gint
DO i=1,gint
JAC=JatG(i)
DO k=1,3
DO j=1,Dof
B(k,j)=BatG(3*(i-1)+k,j)
Bdvdx(k,j)=B(k,j) ! For computation of dv/dx
Bdudy(k,j)=B(k,j) ! For computation of du/dy
DB(k,j)=DBatG(3*(i-1)+k,j)
END DO
END DO
CALL MULT_V(B,3,Dof,U,EPS,3) ! Compute strains EPS
CALL MULT_V(DB,3,Dof,U,SIG,3) ! Compute stresses SIG
W=0.5d0*(EPS(1)*SIG(1)+EPS(2)*SIG(2)+EPS(3)*SIG(3))
c Computation of dv/dx & du/dy
c Set to zero positions in the 3rd row of B associated with dN/dy
DO j=1,Dof,2
Bdvdx(3,j)=0.0d0
END DO
CALL MULT_V(Bdvdx,3,Dof,U,dvdx,3) !compute dv/dx, stored in dvdx(3)
c Set to zero positions in the 3rd row of B associated with dN/dx
DO j=2,Dof,2
Bdudy(3,j)=0.0d0
END DO
CALL MULT_V(Bdudy,3,Dof,U,dudy,3) !compute du/dy, stored in dudy(3)
c Store in SVARS the following information at integration points
SVARS(1+20*(i-1)+1)=EPS(1)
SVARS(1+20*(i-1)+2)=EPS(2)
SVARS(1+20*(i-1)+3)=EPS(3)
SVARS(1+20*(i-1)+4)=SIG(1)
SVARS(1+20*(i-1)+5)=SIG(2)
SVARS(1+20*(i-1)+6)=SIG(3)
SVARS(1+20*(i-1)+7)=W
SVARS(1+20*(i-1)+8)=dvdx(3)
SVARS(1+20*(i-1)+9)=dudy(3)
SVARS(1+20*(i-1)+10)=JAC ! Jacobian includes integration weight
c Store in SVARS the shape functions derivatives dNi/dx, dNi/dy for external computation
c of dq/dx, dq/dy (used in domain interaction integrals).
c (we take them from the positions associated with the standard dofs)
SVARS(1+20*(i-1)+11)=B(1,1)
SVARS(1+20*(i-1)+12)=B(1,13)
SVARS(1+20*(i-1)+13)=B(1,25)
SVARS(1+20*(i-1)+14)=B(1,37)
SVARS(1+20*(i-1)+15)=B(2,2)
SVARS(1+20*(i-1)+16)=B(2,14)
SVARS(1+20*(i-1)+17)=B(2,26)
SVARS(1+20*(i-1)+18)=B(2,38)
Store in SVARS the global coordinates of integration points
SVARS(1+20*(i-1)+19)=xypg(1,i)
SVARS(1+20*(i-1)+20)=xypg(2,i)
END DO !i loop over all integration points of the element
RETURN
END

View file

@ -0,0 +1,70 @@
subroutine uel(rhs,amatrx,svars,energy,ndofel,nrhs,nsvars,
1 props,nprops,coords,mcrd,nnode,u,du,v,a,jtype,time,
2 dtime,kstep,kinc,jelem,params,ndload,jdltyp,adlmag,
3 predef,npredf,lflags,mlvarx,ddlmag,mdload,pnewdt,
4 jprops,njprop,period)
c
include 'aba_param.inc'
parameter ( zero = 0.d0, half = 0.5d0, one = 1.d0 )
c
c This is a linear truss element for Abaqus/Standard
c general static analysis in 1D space (aligned to x-axis) only.
dimension rhs(mlvarx,*),amatrx(ndofel,ndofel),
1 svars(nsvars),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(*),
5 jprops(*)
c
c assign section properties
area = props(1)
e = props(2)
anu = props(3)
rho = props(4)
c calculate stiffness and mass
alen = abs(coords(1,2)-coords(1,1))
ak = area*e/alen
am = half*area*rho*alen
c Initialize Arrays
rhs = zero
amatrx = zero
if (lflags(3).eq.1) then
C Stiffness and Force
C Get Stiffness Matrix
amatrx(1,1) = ak
amatrx(4,4) = ak
amatrx(1,4) = -ak
amatrx(4,1) = -ak
c Get Internal Contrib to Residual Force
rhs(1,1) = -ak*(u(1)-u(4))
rhs(4,1) = -ak*(u(4)-u(1))
c Get External Contrib to Residual Force
do kdload = 1, ndload
if (jdltyp(kdload,1).eq.1001) then
rhs(4,1) = rhs(4,1)+adlmag(kdload,1)
end if
end do
else if (lflags(3).eq.2) then
c Stiffness
amatrx(1,1) = ak
amatrx(4,4) = ak
amatrx(1,4) = -ak
amatrx(4,1) = -ak
else if (lflags(3).eq.4) then
c Mass
do k1 = 1, ndofel
amatrx(k1,k1) = am
end do
else if (lflags(3).eq.5) then
print *,'oops'
else if (lflags(3).eq.6) then
C Mass and Force
do k1 = 1, ndofel
amatrx(k1,k1) = am
end do
rhs(1,1) = -ak*(u(1)-u(4))
rhs(4,1) = -ak*(u(4)-u(1))
END IF
c
return
end

View file

@ -0,0 +1,202 @@
c 1-D Moving Interface User Element - JGrogan 2012.
c Subroutine UEXTERNALDB
c Calculates interface velocity and position at the start of each increment
c and passes it to UEL via common block. It requires a list of current nodal
c coordinates, and 'T' and 'a' degrees of freedom.
subroutine uexternaldb(lop,lrestart,time,dtime,kstep,kinc)
c
include 'aba_param.inc'
c
real dpos, npos(6), ndof(6)
common dpos,npos,ndof
dimension time(2)
c
if (lop==0)then
c initialise common blocks
dpos=0.
npos=0.
tn=0.
an=0.
print *,'npos',npos,'extrn1',time
print *,'ndof',ndof,'extrn1',time
else
print *,'npos',npos,'extrn',time
print *,'ndof',ndof,'extrn',time
endif
return
end
c
c Subroutine UEL
c Calculates element mass and stiffness matrices and residual flux
c vector for Abaqus NR Solver.
subroutine uel(rhs,amatrx,svars,energy,ndofel,nrhs,nsvars,props
1 ,nprops,coords,mcrd,nnode,u,du,v,a,jtype,time,dtime,kstep,
2 kinc,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 gpx(4),gwei(4),phi(4),phix(4),phic(4),gm(4),gm2(4,4)
dimension theta(2)
real dpos, npos(6), ndof(6)
common dpos,npos,ndof
c
c level set calculation
c store nodal positions and temperatures
npos(jelem)=coords(1,1)
npos(jelem+1)=coords(1,2)
ndof(2*jelem-1)=u(1)
ndof(2*jelem)=u(2)
dpos1=0.2+0.4*time(1)
c print *,'npos',npos,'uel',time
c print *,'ndof',ndof,'uel',time
c material property definition
rho = 1.
spec = 1.
c penalty term
beta=40.
c initialization (nrhs=1)
do k1=1,ndofel
rhs(k1,nrhs)=0.
do k2=1,ndofel
amatrx(k2,k1)=0.
enddo
enddo
if (lflags(3).eq.4) return
c transient analysis
if (lflags(1).eq.33) then
c determine node level set params
crdn1=coords(1,1)
crdn2=coords(1,2)
theta(1)=abs(crdn1-dpos1)*sign(1.,crdn1-dpos1)
theta(2)=abs(crdn2-dpos1)*sign(1.,crdn2-dpos1)
enr=2
elen=abs(crdn2-crdn1)
ajacob=elen/2.
if (sign(1.,theta(1))/=sign(1.,theta(2)))then
c enriched element
enr=4
point=(dpos1-crdn1)/ajacob-1.
rlen1=abs(-point-1.)
rlen2=abs(1.-point)
rmid1=-1.+rlen1/2.
rmid2=1.-rlen2/2.
c Get int point locations and weights
gpx(1)=-(rlen1/2.)/sqrt(3.)+rmid1
gpx(2)=(rlen1/2.)/sqrt(3.)+rmid1
gpx(3)=-(rlen2/2.)/sqrt(3.)+rmid2
gpx(4)=(rlen2/2.)/sqrt(3.)+rmid2
gwei(1)=(rlen1/2.)
gwei(2)=(rlen1/2.)
gwei(3)=(rlen2/2.)
gwei(4)=(rlen2/2.)
else
c regular element
gpx(1)=-1./sqrt(3.)
gpx(2)=1./sqrt(3.)
gwei(1)=1.
gwei(2)=1.
endif
c assemble amatrx and rhs
do k=1,enr
c loop through gauss pts: i
c=gpx(k)
c get ip level set value: Oi
c get shape functions and derivatives
c Ni
phi(1)=(1.-c)/2.
phi(3)=(1.+c)/2.
term=theta(1)*phi(1)+theta(2)*phi(3)
if (term<0.)then
cond=0.
spec=0.1
else
cond=1.
spec=1.
endif
if(enr==4)then
phi(2)=phi(1)*(abs(term)-abs(theta(1)))
phi(4)=phi(3)*(abs(term)-abs(theta(2)))
else
phi(2)=0.
phi(4)=0.
endif
c dNdci
phic(1)=-0.5
phic(3)=0.5
dterm=sign(1.,term)*(phic(1)*theta(1)+phic(3)*theta(2))
if(enr==4)then
phic(2)=phic(1)*(abs(term)-abs(theta(1)))
1 +phi(1)*dterm
phic(4)=phic(3)*(abs(term)-abs(theta(2)))
1 +phi(3)*dterm
else
phic(2)=0.
phic(4)=0.
endif
c dNdxi
phix(1)=phic(1)*(1./ajacob)
phix(2)=phic(2)*(1./ajacob)
phix(3)=phic(3)*(1./ajacob)
phix(4)=phic(4)*(1./ajacob)
c interpolate temperatures Tbar to int point: i
dtdx=u(1)*phix(1)+u(2)*phix(2)
1 +u(3)*phix(3)+u(4)*phix(4)
t=u(1)*phi(1)+u(2)*phi(2)
1 +u(3)*phi(3)+u(4)*phi(4)
told=(u(1)-du(1,nrhs))*phi(1)+(u(2)-du(2,nrhs))*phi(2)+
1 (u(3)-du(3,nrhs))*phi(3)+(u(4)-du(4,nrhs))*phi(4)
c other housekeeping
dtdt=(t-told)/dtime
we=gwei(k)*ajacob
c Assemble Element Stiffness Matrix and Add to Global
do ki=1,4
c loop over nodes
rhs(ki,nrhs)=rhs(ki,nrhs)-we*(phi(ki)*rho*spec*dtdt
1 + cond*(phix(ki)*dtdx))
do kj=1,4
amatrx(ki,kj)=amatrx(ki,kj)+we*(phi(ki)*phi(kj)
1 *rho*spec/dtime+cond*(phix(ki)*phix(kj)))
end do
end do
enddo
end if
c if interface is in the element an 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
return
end

View file

@ -0,0 +1,165 @@
c Subroutine UEL
c Calculates element mass and stiffness matrices and residual flux
c vector for Abaqus NR Solver.
subroutine uel(rhs,amatrx,svars,energy,ndofel,nrhs,nsvars,props
1 ,nprops,coords,mcrd,nnode,u,du,v,a,jtype,time,dtime,kstep,
2 kinc,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 gpx(4),gwei(4),phi(4),phix(4),phic(4),gm(4),gm2(4,4)
dimension theta(2)
real dpos, npos(6), ndof(6)
common dpos,npos,ndof
c
c level set calculation
c store nodal positions and temperatures
dpos1=0.6
c material property definition
rho = 1.
spec = 1.
c penalty term
beta=100.
c initialization (nrhs=1)
do k1=1,ndofel
rhs(k1,nrhs)=0.
do k2=1,ndofel
amatrx(k2,k1)=0.
enddo
enddo
if (lflags(3).eq.4) return
c transient analysis
if (lflags(1).eq.33) then
c determine node level set params
crdn1=coords(1,1)
crdn2=coords(1,2)
theta(1)=abs(crdn1-dpos1)*sign(1.,crdn1-dpos1)
theta(2)=abs(crdn2-dpos1)*sign(1.,crdn2-dpos1)
enr=2
elen=abs(crdn2-crdn1)
ajacob=elen/2.
if (sign(1.,theta(1))/=sign(1.,theta(2)))then
c enriched element
enr=4
point=(dpos1-crdn1)/ajacob-1.
rlen1=abs(-point-1.)
rlen2=abs(1.-point)
rmid1=-1.+rlen1/2.
rmid2=1.-rlen2/2.
c Get int point locations and weights
gpx(1)=-(rlen1/2.)/sqrt(3.)+rmid1
gpx(2)=(rlen1/2.)/sqrt(3.)+rmid1
gpx(3)=-(rlen2/2.)/sqrt(3.)+rmid2
gpx(4)=(rlen2/2.)/sqrt(3.)+rmid2
gwei(1)=(rlen1/2.)
gwei(2)=(rlen1/2.)
gwei(3)=(rlen2/2.)
gwei(4)=(rlen2/2.)
else
c regular element
gpx(1)=-1./sqrt(3.)
gpx(2)=1./sqrt(3.)
gwei(1)=1.
gwei(2)=1.
endif
c assemble amatrx and rhs
do k=1,enr
c loop through gauss pts: i
c=gpx(k)
c get ip level set value: Oi
c get shape functions and derivatives
c Ni
phi(1)=(1.-c)/2.
phi(3)=(1.+c)/2.
term=theta(1)*phi(1)+theta(2)*phi(3)
c if (term<0.)then
c cond=0.
c spec=0.1
c else
cond=1.
spec=1.
c endif
c if(enr==4)then
phi(2)=phi(1)*(abs(term)-abs(theta(1)))
phi(4)=phi(3)*(abs(term)-abs(theta(2)))
c else
c phi(2)=0.
c phi(4)=0.
c endif
c dNdci
phic(1)=-0.5
phic(3)=0.5
dterm=sign(1.,term)*(phic(1)*theta(1)+phic(3)*theta(2))
c if(enr==4)then
phic(2)=phic(1)*(abs(term)-abs(theta(1)))
1 +phi(1)*dterm
phic(4)=phic(3)*(abs(term)-abs(theta(2)))
1 +phi(3)*dterm
c else
c phic(2)=0.
c phic(4)=0.
c endif
c dNdxi
phix(1)=phic(1)*(1./ajacob)
phix(2)=phic(2)*(1./ajacob)
phix(3)=phic(3)*(1./ajacob)
phix(4)=phic(4)*(1./ajacob)
c interpolate temperatures Tbar to int point: i
dtdx=u(1)*phix(1)+u(2)*phix(2)
1 +u(3)*phix(3)+u(4)*phix(4)
t=u(1)*phi(1)+u(2)*phi(2)
1 +u(3)*phi(3)+u(4)*phi(4)
told=(u(1)-du(1,nrhs))*phi(1)+(u(2)-du(2,nrhs))*phi(2)+
1 (u(3)-du(3,nrhs))*phi(3)+(u(4)-du(4,nrhs))*phi(4)
c other housekeeping
dtdt=(t-told)/dtime
we=gwei(k)*ajacob
c Assemble Element Stiffness Matrix and Add to Global
do ki=1,4
c loop over nodes
rhs(ki,nrhs)=rhs(ki,nrhs)-we*(phi(ki)*rho*spec*dtdt
1 + cond*(phix(ki)*dtdx))
do kj=1,4
amatrx(ki,kj)=amatrx(ki,kj)+we*(phi(ki)*phi(kj)
1 *rho*spec/dtime+cond*(phix(ki)*phix(kj)))
end do
end do
enddo
end if
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
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
return
end

View file

@ -0,0 +1,80 @@
subroutine uel(rhs,amatrx,svars,energy,ndofel,nrhs,nsvars,props
1 ,nprops,coords,mcrd,nnode,u,du,v,a,jtype,time,dtime,kstep,
2 kinc,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 gpx(9),gwei(9),phi(8),phix(8),phic(8),stiffk(2,2)
dimension stiffm(2,2)
c
c print *,u(1),u(2),du(1,nhrs),du(2,nhrs),time(1),lflags(3)
c material property definition
rho = 1.
spec = 1.
conduc = 1.
c initialization (nrhs=1)
do k1=1,ndofel
rhs(k1,nrhs)=0.
do k2=1,ndofel
amatrx(k2,k1)=0.
stiffk(k2,k1)=0.
stiffm(k2,k1)=0.
enddo
enddo
if (lflags(3).eq.4) return
c transient analysis
if (lflags(1).eq.33) then
c determine gauss point locations
gpx(1)=-1./sqrt(3.)
gpx(2)=1./sqrt(3.)
gwei(1)=1.
gwei(2)=1.
c assemble amatrx and rhs
do k=1,2
c loop through gauss pts
c=gpx(k)
c get shape functions and derivatives
phi(1)=(1.-c)/2.
phi(2)=(1.+c)/2.
phic(1)=-0.5
phic(2)=0.5
dxdc=abs(coords(1,2)-coords(1,1))/2.
ajacob=dxdc
phix(1)=phic(1)*(1./ajacob)
phix(2)=phic(2)*(1./ajacob)
c interpolate temperatures to int points
dtdx=u(1)*phix(1)+u(2)*phix(2)
t=u(1)*phi(1)+u(2)*phi(2)
told=(u(1)-du(1,nrhs))*phi(1)+(u(2)-du(2,nrhs))*phi(2)
c other housekeeping
cond=conduc
dtdt=(t-told)/dtime
we=gwei(k)*ajacob
c Assemble Element Stiffness Matrix and Add to Global
do ki=1,2
c loop over nodes
rhs(ki,nrhs)=rhs(ki,nrhs)-we*(phi(ki)*rho*spec*dtdt
1 + cond*(phix(ki)*dtdx))
do kj=1,2
stiffk(ki,kj)=stiffk(ki,kj)+
1 we*cond*(phix(ki)*phix(kj))
stiffm(ki,kj)=stiffm(ki,kj)+
1 we*(phi(ki)*phi(kj)*rho*spec)/dtime
end do
end do
do i=1,2
do j=1,2
amatrx(i,j)=stiffk(i,j)+stiffm(i,j)
enddo
enddo
enddo
end if
return
end

View file

@ -0,0 +1,81 @@
subroutine uel(rhs,amatrx,svars,energy,ndofel,nrhs,nsvars,props
1 ,nprops,coords,mcrd,nnode,u,du,v,a,jtype,time,dtime,kstep,
2 kinc,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 gpx(9),gwei(9),phi(8),phix(8),phic(8)
c
c print *,u(1),u(2),du(1,nhrs),du(2,nhrs),time(1),lflags(3)
c level set calculation
dpos=0.01*time
c
c material property definition
rho = 1.
spec = 1.
conduc = 1.
c initialization (nrhs=1)
do k1=1,ndofel
rhs(k1,nrhs)=0.
do k2=1,ndofel
amatrx(k2,k1)=0.
enddo
enddo
if (lflags(3).eq.4) return
c transient analysis
if (lflags(1).eq.33) then
c determine gauss point locations
gpx(1)=-1./sqrt(3.)
gpx(2)=1./sqrt(3.)
gwei(1)=1.
gwei(2)=1.
c determine node level sets
rnl1=abs(coords(1,1)-dpos)
rnl2=abs(coords(1,2)-dpos)
c get jacobian
dxdc=abs(coords(1,2)-coords(1,1))/2.
ajacob=dxdc
c assemble amatrx and rhs
do k=1,4
c loop through gauss pts
c=gpx(k)
c get shape functions and derivatives
phi(1)=(1.-c)/2.
phi(2)=(1.+c)/2.
c get ip position
pos=coord(1,1)+ajacob(1.+c)
phi(3)=abs(c)
phic(1)=-0.5
phic(2)=0.5
phix(1)=phic(1)*(1./ajacob)
phix(2)=phic(2)*(1./ajacob)
c interpolate temperatures to int points
dtdx=u(1)*phix(1)+u(2)*phix(2)
t=u(1)*phi(1)+u(2)*phi(2)
told=(u(1)-du(1,nrhs))*phi(1)+(u(2)-du(2,nrhs))*phi(2)
c other housekeeping
cond=conduc
dtdt=(t-told)/dtime
we=gwei(k)*ajacob
c Assemble Element Stiffness Matrix and Add to Global
do ki=1,2
c loop over nodes
rhs(ki,nrhs)=rhs(ki,nrhs)-we*(phi(ki)*rho*spec*dtdt
1 + cond*(phix(ki)*dtdx))
do kj=1,2
amatrx(ki,kj)=amatrx(ki,kj)+we*(phi(ki)*phi(kj)
1 *rho*spec/dtime+cond*(phix(ki)*phix(kj)))
end do
end do
enddo
end if
return
end

View file

@ -0,0 +1,202 @@
c 1-D Moving Interface User Element - JGrogan 2012.
c Subroutine UEXTERNALDB
c Calculates interface velocity and position at the start of each increment
c and passes it to UEL via common block. It requires a list of current nodal
c coordinates, and 'T' and 'a' degrees of freedom.
subroutine uexternaldb(lop,lrestart,time,dtime,kstep,kinc)
c
include 'aba_param.inc'
c
real dpos, npos(6), ndof(6)
common dpos,npos,ndof
dimension time(2)
c
if (lop==0)then
c initialise common blocks
dpos=0.
npos=0.
tn=0.
an=0.
print *,'npos',npos,'extrn1',time
print *,'ndof',ndof,'extrn1',time
else
print *,'npos',npos,'extrn',time
print *,'ndof',ndof,'extrn',time
endif
return
end
c
c Subroutine UEL
c Calculates element mass and stiffness matrices and residual flux
c vector for Abaqus NR Solver.
subroutine uel(rhs,amatrx,svars,energy,ndofel,nrhs,nsvars,props
1 ,nprops,coords,mcrd,nnode,u,du,v,a,jtype,time,dtime,kstep,
2 kinc,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 gpx(4),gwei(4),phi(4),phix(4),phic(4),gm(4),gm2(4,4)
dimension theta(2)
real dpos, npos(6), ndof(6)
common dpos,npos,ndof
c
c level set calculation
c store nodal positions and temperatures
npos(jelem)=coords(1,1)
npos(jelem+1)=coords(1,2)
ndof(2*jelem-1)=u(1)
ndof(2*jelem)=u(2)
dpos1=0.2+0.4*time(1)
c print *,'npos',npos,'uel',time
c print *,'ndof',ndof,'uel',time
c material property definition
rho = 1.
spec = 1.
c penalty term
beta=40.
c initialization (nrhs=1)
do k1=1,ndofel
rhs(k1,nrhs)=0.
do k2=1,ndofel
amatrx(k2,k1)=0.
enddo
enddo
if (lflags(3).eq.4) return
c transient analysis
if (lflags(1).eq.33) then
c determine node level set params
crdn1=coords(1,1)
crdn2=coords(1,2)
theta(1)=abs(crdn1-dpos1)*sign(1.,crdn1-dpos1)
theta(2)=abs(crdn2-dpos1)*sign(1.,crdn2-dpos1)
enr=2
elen=abs(crdn2-crdn1)
ajacob=elen/2.
if (sign(1.,theta(1))/=sign(1.,theta(2)))then
c enriched element
enr=4
point=(dpos1-crdn1)/ajacob-1.
rlen1=abs(-point-1.)
rlen2=abs(1.-point)
rmid1=-1.+rlen1/2.
rmid2=1.-rlen2/2.
c Get int point locations and weights
gpx(1)=-(rlen1/2.)/sqrt(3.)+rmid1
gpx(2)=(rlen1/2.)/sqrt(3.)+rmid1
gpx(3)=-(rlen2/2.)/sqrt(3.)+rmid2
gpx(4)=(rlen2/2.)/sqrt(3.)+rmid2
gwei(1)=(rlen1/2.)
gwei(2)=(rlen1/2.)
gwei(3)=(rlen2/2.)
gwei(4)=(rlen2/2.)
else
c regular element
gpx(1)=-1./sqrt(3.)
gpx(2)=1./sqrt(3.)
gwei(1)=1.
gwei(2)=1.
endif
c assemble amatrx and rhs
do k=1,enr
c loop through gauss pts: i
c=gpx(k)
c get ip level set value: Oi
c get shape functions and derivatives
c Ni
phi(1)=(1.-c)/2.
phi(3)=(1.+c)/2.
term=theta(1)*phi(1)+theta(2)*phi(3)
if (term<0.)then
cond=0.
spec=0.1
else
cond=1.
spec=1.
endif
if(enr==4)then
phi(2)=phi(1)*(abs(term)-abs(theta(1)))
phi(4)=phi(3)*(abs(term)-abs(theta(2)))
else
phi(2)=0.
phi(4)=0.
endif
c dNdci
phic(1)=-0.5
phic(3)=0.5
dterm=sign(1.,term)*(phic(1)*theta(1)+phic(3)*theta(2))
if(enr==4)then
phic(2)=phic(1)*(abs(term)-abs(theta(1)))
1 +phi(1)*dterm
phic(4)=phic(3)*(abs(term)-abs(theta(2)))
1 +phi(3)*dterm
else
phic(2)=0.
phic(4)=0.
endif
c dNdxi
phix(1)=phic(1)*(1./ajacob)
phix(2)=phic(2)*(1./ajacob)
phix(3)=phic(3)*(1./ajacob)
phix(4)=phic(4)*(1./ajacob)
c interpolate temperatures Tbar to int point: i
dtdx=u(1)*phix(1)+u(2)*phix(2)
1 +u(3)*phix(3)+u(4)*phix(4)
t=u(1)*phi(1)+u(2)*phi(2)
1 +u(3)*phi(3)+u(4)*phi(4)
told=(u(1)-du(1,nrhs))*phi(1)+(u(2)-du(2,nrhs))*phi(2)+
1 (u(3)-du(3,nrhs))*phi(3)+(u(4)-du(4,nrhs))*phi(4)
c other housekeeping
dtdt=(t-told)/dtime
we=gwei(k)*ajacob
c Assemble Element Stiffness Matrix and Add to Global
do ki=1,4
c loop over nodes
rhs(ki,nrhs)=rhs(ki,nrhs)-we*(phi(ki)*rho*spec*dtdt
1 + cond*(phix(ki)*dtdx))
do kj=1,4
amatrx(ki,kj)=amatrx(ki,kj)+we*(phi(ki)*phi(kj)
1 *rho*spec/dtime+cond*(phix(ki)*phix(kj)))
end do
end do
enddo
end if
c if interface is in the element an 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
return
end

View file

@ -0,0 +1,114 @@
subroutine uel(rhs,amatrx,svars,energy,ndofel,nrhs,nsvars,props
1 ,nprops,coords,mcrd,nnode,u,du,v,a,jtype,time,dtime,kstep,
2 kinc,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 gx(4),hx(4),phi(4),phix(4),phiy(4),phig(4),phih(4)
dimension rjac(2,2),rjaci(2,2)
c
c material property definition
rho = 1.
spec = 1.
cond = 1.
c initialization (nrhs=1)
do k1=1,ndofel
rhs(k1,nrhs)=0.
do k2=1,ndofel
amatrx(k2,k1)=0.
enddo
enddo
if (lflags(3).eq.4) return
c transient analysis
if (lflags(1).eq.33) then
c determine gauss point locations
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
c assemble amatrx and rhs
do k=1,4
c loop through gauss pts
g=gx(k)
h=hx(k)
c get shape functions and derivatives
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)
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)
c get ip coords
crdx=0.
crdy=0.
do k1=1,4
crdx=crdx+phi(k1)*coords(1,k1)
crdy=crdy+phi(k1)*coords(2,k1)
end do
c get jacobian
rjac=0.
do i=1,4
rjac(1,1)=rjac(1,1)+phig(i)*coords(1,i)
rjac(1,2)=rjac(1,2)+phig(i)*coords(2,i)
rjac(2,1)=rjac(2,1)+phih(i)*coords(1,i)
rjac(2,2)=rjac(2,2)+phih(i)*coords(2,i)
enddo
djac=rjac(1,1)*rjac(2,2)-rjac(1,2)*rjac(2,1)
print *,djac
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
c get b matrix
phix(1)=rjaci(1,1)*phig(1)+rjaci(1,2)*phih(1)
phiy(1)=rjaci(2,1)*phig(1)+rjaci(2,2)*phih(1)
phix(2)=rjaci(1,1)*phig(2)+rjaci(1,2)*phih(2)
phiy(2)=rjaci(2,1)*phig(2)+rjaci(2,2)*phih(2)
phix(3)=rjaci(1,1)*phig(3)+rjaci(1,2)*phih(3)
phiy(3)=rjaci(2,1)*phig(3)+rjaci(2,2)*phih(3)
phix(4)=rjaci(1,1)*phig(4)+rjaci(1,2)*phih(4)
phiy(4)=rjaci(2,1)*phig(4)+rjaci(2,2)*phih(4)
c interpolate temperatures to int points
dtdx=u(1)*phix(1)+u(2)*phix(2)
1 +u(3)*phix(3)+u(4)*phix(4)
dtdy=u(1)*phiy(1)+u(2)*phiy(2)
1 +u(3)*phiy(3)+u(4)*phiy(4)
t=u(1)*phi(1)+u(2)*phi(2)+u(3)*phi(3)+u(4)*phi(4)
told=(u(1)-du(1,nrhs))*phi(1)+(u(2)-du(2,nrhs))*phi(2)+
1 (u(3)-du(3,nrhs))*phi(3)+(u(4)-du(4,nrhs))*phi(4)
c other housekeeping
dtdt=(t-told)/dtime
we=djac
c Assemble Element Stiffness Matrix and Add to Global
do ki=1,4
c loop over nodes
rhs(ki,nrhs)=rhs(ki,nrhs)-we*(phi(ki)*rho*spec*dtdt
1 + cond*(phix(ki)*dtdx+phiy(ki)*dtdy))
do kj=1,4
amatrx(ki,kj)=amatrx(ki,kj)+we*(phi(ki)*phi(kj)
1 *rho*spec/dtime+cond*(phix(ki)*phix(kj)+
1 phiy(ki)*phiy(kj)))
end do
end do
enddo
end if
return
end

View file

@ -0,0 +1,198 @@
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 GPX(9),GPY(9),GWEI(9),PHI(8),PHIX(8),PHIY(8),PHIC(8),
1 PHIE(8),IFACE(9),GWE(3),AR(3)
C
PARAMETER(ZERO=0.D0,TWOHUN=200.D0,FIVHUN=500.D0,CONDUC=204.D0)
DATA IFACE/1,5,2,6,3,7,4,8,1/
C
C
C MATERIAL PROPERTY DEFINITION
C
THICK = PROPS(1)
RHO = PROPS(2)
SPEC = PROPS(3)
C
C INITIALIZATION (NRHS=1)
C
DO 6 K1=1,NDOFEL
RHS(K1,NRHS)=ZERO
DO 4 K2=1,NDOFEL
AMATRX(K2,K1)=ZERO
4 CONTINUE
6 CONTINUE
C
IF (LFLAGS(3).EQ.4) RETURN
C
C TRANSIENT ANALYSIS
C
IF (LFLAGS(1).EQ.33) THEN
C
C DETERMINE GAUSS POINT LOCATIONS
C
SUBROUTINE GSPT(GPX,GPY)
INCLUDE 'aba_param.inc'
DIMENSION AR(3),GPX(9),GPY(9)
C
PARAMETER(ZERO=0.D0,ONENEG=-1.D0,ONE=1.D0,SIX=6.D0,TEN=10.D0)
C
C GPX: X COORDINATE OF GAUSS PT
C GPY: Y COORDINATE OF GAUSS PT
C
R=SQRT(SIX/TEN)
AR(1)=-1.
AR(2)=0.
AR(3)=1.
DO 10 I=1,3
DO 10 J=1,3
NUMGP=(I-1)*3+J
GPX(NUMGP)=AR(I)*R
GPY(NUMGP)=AR(J)*R
10 CONTINUE
RETURN
END
CALL GSPT(GPX,GPY)
C
C DETERMINE GAUSS WEIGHTS
C
CALL GSWT(GWEI,GWE)
C
C ASSEMBLE AMATRX AND RHS
C
DO 300 K=1,9
C LOOP THROUGH GAUSS PTS
C=GPX(K)
E=GPY(K)
CALL DER(C,E,GPX,GPY,GWEI,PHI,PHIX,PHIY,PHIC,PHIE
1 ,DXDC,DXDE,DYDC,DYDE,AJACOB,COORDS,MCRD,NNODE)
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
C CHECK ON TEMPERATURE DEPENDENCE OF THERMAL CONDUCTIVITY
COND=CONDUC
DCDT=ZERO
DTDT=(T-TOLD)/DTIME
WE=GWEI(K)*AJACOB
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) + WE*(PHI(KI)*PHI(KJ)*RHO*
1 SPEC/DTIME + COND*(PHIX(KI)*PHIX(KJ) + PHIY(KI)*
2 PHIY(KJ)) + DCDT*PHI(KJ)*(PHIX(KI)*DTDX +
3 PHIY(KI)*DTDY))
END DO
END DO
300 CONTINUE
C
RETURN
END
C
C
SUBROUTINE GSWT(GWEI,GWE)
INCLUDE 'aba_param.inc'
DIMENSION GWEI(9),GWE(3)
C
PARAMETER(FIVE=5.D0,EIGHT=8.D0,NINE=9.D0)
C
C GWEI : GAUSS WEIGHT
C
GWE(1)=FIVE/NINE
GWE(2)=EIGHT/NINE
GWE(3)=FIVE/NINE
DO 10 I=1,3
DO 10 J=1,3
NUMGP=(I-1)*3+J
GWEI(NUMGP)=GWE(I)*GWE(J)
10 CONTINUE
RETURN
END
C
SUBROUTINE DER(C,E,GPX,GPY,GWEI,PHI,PHIX,PHIY,PHIC,PHIE,
1 DXDC,DXDE,DYDC,DYDE,AJACOB,COORDS,MCRD,NNODE)
INCLUDE 'aba_param.inc'
DIMENSION PHI(8),PHIX(8),PHIY(8),PHIC(8),PHIE(8),
1 COORDS(MCRD,NNODE)
C
PARAMETER(ZERO=0.D0,FOURTH=0.25D0,HALF=0.5D0,ONE=1.D0,TWO=2.D0)
C
C INTERPOLATION FUNCTIONS
C
PHI(1) = FOURTH*(ONE-C)*(ONE-E)*(-C-E-ONE)
PHI(2) = FOURTH*(ONE+C)*(ONE-E)*(C-E-ONE)
PHI(3) = FOURTH*(ONE+C)*(ONE+E)*(C+E-ONE)
PHI(4) = FOURTH*(ONE-C)*(ONE+E)*(-C+E-ONE)
PHI(5) = HALF*(ONE-C*C)*(ONE-E)
PHI(6) = HALF*(ONE+C)*(ONE-E*E)
PHI(7) = HALF*(ONE-C*C)*(ONE+E)
PHI(8) = HALF*(ONE-C)*(ONE-E*E)
C
C DERIVATIVES WRT TO C
C
PHIC(1) = FOURTH*(ONE-E)*(TWO*C+E)
PHIC(2) = FOURTH*(ONE-E)*(TWO*C-E)
PHIC(3) = FOURTH*(ONE+E)*(TWO*C+E)
PHIC(4) = FOURTH*(ONE+E)*(TWO*C-E)
PHIC(5) = -C*(ONE-E)
PHIC(6) = HALF*(ONE-E*E)
PHIC(7) = -C*(ONE+E)
PHIC(8) = -HALF*(ONE-E*E)
C
C DERIVATIVES WRT TO E
C
PHIE(1) = FOURTH*(ONE-C)*(TWO*E+C)
PHIE(2) = FOURTH*(ONE+C)*(TWO*E-C)
PHIE(3) = FOURTH*(ONE+C)*(TWO*E+C)
PHIE(4) = FOURTH*(ONE-C)*(TWO*E-C)
PHIE(5) = -HALF*(ONE-C*C)
PHIE(6) = -E*(ONE+C)
PHIE(7) = HALF*(ONE-C*C)
PHIE(8) = -E*(ONE-C)
DXDC=ZERO
DXDE=ZERO
DYDC=ZERO
DYDE=ZERO
DO 3 I=1,8
DXDC=DXDC+COORDS(1,I)*PHIC(I)
DXDE=DXDE+COORDS(1,I)*PHIE(I)
DYDC=DYDC+COORDS(2,I)*PHIC(I)
DYDE=DYDE+COORDS(2,I)*PHIE(I)
3 CONTINUE
C
C CALCULATION OF JACOBIAN
C
AJACOB=(DXDC*DYDE-DXDE*DYDC)
C
C DERIVATIVES WRT TO X AND Y
C
DO 5 I=1,8
PHIX(I)=(PHIC(I)*DYDE-PHIE(I)*DYDC)/AJACOB
PHIY(I)=(PHIE(I)*DXDC-PHIC(I)*DXDE)/AJACOB
5 CONTINUE
RETURN
END

View file

@ -0,0 +1,192 @@
SUBROUTINE UEL(RHS,AMATRX,SVARS,ENERGY,NDOFEL,NRHS,NSVARS,
1 PROPS,NPROPS,COORDS,MCRD,NNODE,U,DU,V,A,JTYPE,TIME,
2 DTIME,KSTEP,KINC,JELEM,PARAMS,NDLOAD,JDLTYP,ADLMAG,
3 PREDEF,NPREDF,LFLAGS,MLVARX,DDLMAG,MDLOAD,PNEWDT,
4 JPROPS,NJPROP,PERIOD)
C
INCLUDE 'ABA_PARAM.INC'
PARAMETER ( ZERO = 0.D0, HALF = 0.5D0, ONE = 1.D0 )
C
DIMENSION RHS(MLVARX,*),AMATRX(NDOFEL,NDOFEL),
1 SVARS(NSVARS),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(*),
5 JPROPS(*)
DIMENSION SRESID(6)
C
C UEL SUBROUTINE FOR A HORIZONTAL TRUSS ELEMENT
C
C SRESID - stores the static residual at time t+dt
C SVARS - In 1-6, contains the static residual at time t
C upon entering the routine. SRESID is copied to
C SVARS(1-6) after the dynamic residual has been
C calculated.
C - For half-increment residual calculations: In 7-12,
C contains the static residual at the beginning
C of the previous increment. SVARS(1-6) are copied
C into SVARS(7-12) after the dynamic residual has
C been calculated.
C
AREA = PROPS(1)
E = PROPS(2)
ANU = PROPS(3)
RHO = PROPS(4)
C
ALEN = ABS(COORDS(1,2)-COORDS(1,1))
AK = AREA*E/ALEN
AM = HALF*AREA*RHO*ALEN
C
DO K1 = 1, NDOFEL
SRESID(K1) = ZERO
DO KRHS = 1, NRHS
RHS(K1,KRHS) = ZERO
END DO
DO K2 = 1, NDOFEL
AMATRX(K2,K1) = ZERO
END DO
END DO
C
IF (LFLAGS(3).EQ.1) THEN
C Normal incrementation
IF (LFLAGS(1).EQ.1 .OR. LFLAGS(1).EQ.2) THEN
C *STATIC
AMATRX(1,1) = AK
AMATRX(4,4) = AK
AMATRX(1,4) = -AK
AMATRX(4,1) = -AK
IF (LFLAGS(4).NE.0) THEN
FORCE = AK*(U(4)-U(1))
DFORCE = AK*(DU(4,1)-DU(1,1))
SRESID(1) = -DFORCE
SRESID(4) = DFORCE
RHS(1,1) = RHS(1,1)-SRESID(1)
RHS(4,1) = RHS(4,1)-SRESID(4)
ENERGY(2) = HALF*FORCE*(DU(4,1)-DU(1,1))
* + HALF*DFORCE*(U(4)-U(1))
* + HALF*DFORCE*(DU(4,1)-DU(1,1))
ELSE
FORCE = AK*(U(4)-U(1))
SRESID(1) = -FORCE
SRESID(4) = FORCE
RHS(1,1) = RHS(1,1)-SRESID(1)
RHS(4,1) = RHS(4,1)-SRESID(4)
DO KDLOAD = 1, NDLOAD
IF (JDLTYP(KDLOAD,1).EQ.1001) THEN
RHS(4,1) = RHS(4,1)+ADLMAG(KDLOAD,1)
ENERGY(8) = ENERGY(8)+(ADLMAG(KDLOAD,1)
* - HALF*DDLMAG(KDLOAD,1))*DU(4,1)
IF (NRHS.EQ.2) THEN
C Riks
RHS(4,2) = RHS(4,2)+DDLMAG(KDLOAD,1)
END IF
END IF
END DO
ENERGY(2) = HALF*FORCE*(U(4)-U(1))
END IF
ELSE IF (LFLAGS(1).EQ.11 .OR. LFLAGS(1).EQ.12) THEN
C *DYNAMIC
ALPHA = PARAMS(1)
BETA = PARAMS(2)
GAMMA = PARAMS(3)
C
DADU = ONE/(BETA*DTIME**2)
DVDU = GAMMA/(BETA*DTIME)
C
DO K1 = 1, NDOFEL
AMATRX(K1,K1) = AM*DADU
RHS(K1,1) = RHS(K1,1)-AM*A(K1)
END DO
AMATRX(1,1) = AMATRX(1,1)+(ONE+ALPHA)*AK
AMATRX(4,4) = AMATRX(4,4)+(ONE+ALPHA)*AK
AMATRX(1,4) = AMATRX(1,4)-(ONE+ALPHA)*AK
AMATRX(4,1) = AMATRX(4,1)-(ONE+ALPHA)*AK
FORCE = AK*(U(4)-U(1))
SRESID(1) = -FORCE
SRESID(4) = FORCE
RHS(1,1) = RHS(1,1) -
* ((ONE+ALPHA)*SRESID(1)-ALPHA*SVARS(1))
RHS(4,1) = RHS(4,1) -
* ((ONE+ALPHA)*SRESID(4)-ALPHA*SVARS(4))
ENERGY(1) = ZERO
DO K1 = 1, NDOFEL
SVARS(K1+6) = SVARS(k1)
SVARS(K1) = SRESID(K1)
ENERGY(1) = ENERGY(1)+HALF*V(K1)*AM*V(K1)
END DO
ENERGY(2) = HALF*FORCE*(U(4)-U(1))
END IF
ELSE IF (LFLAGS(3).EQ.2) THEN
C Stiffness matrix
AMATRX(1,1) = AK
AMATRX(4,4) = AK
AMATRX(1,4) = -AK
AMATRX(4,1) = -AK
ELSE IF (LFLAGS(3).EQ.4) THEN
C Mass matrix
DO K1 = 1, NDOFEL
AMATRX(K1,K1) = AM
END DO
ELSE IF (LFLAGS(3).EQ.5) THEN
C Half-increment residual calculation
ALPHA = PARAMS(1)
FORCE = AK*(U(4)-U(1))
SRESID(1) = -FORCE
SRESID(4) = FORCE
RHS(1,1) = RHS(1,1)-AM*A(1)-(ONE+ALPHA)*SRESID(1)
* + HALF*ALPHA*( SVARS(1)+SVARS(7) )
RHS(4,1) = RHS(4,1)-AM*A(4)-(ONE+ALPHA)*SRESID(4)
* + HALF*ALPHA*( SVARS(4)+SVARS(10) )
ELSE IF (LFLAGS(3).EQ.6) THEN
C Initial acceleration calculation
DO K1 = 1, NDOFEL
AMATRX(K1,K1) = AM
END DO
FORCE = AK*(U(4)-U(1))
SRESID(1) = -FORCE
SRESID(4) = FORCE
RHS(1,1) = RHS(1,1)-SRESID(1)
RHS(4,1) = RHS(4,1)-SRESID(4)
ENERGY(1) = ZERO
DO K1 = 1, NDOFEL
SVARS(K1) = SRESID(K1)
ENERGY(1) = ENERGY(1)+HALF*V(K1)*AM*V(K1)
END DO
ENERGY(2) = HALF*FORCE*(U(4)-U(1))
ELSE IF (LFLAGS(3).EQ.100) THEN
C Output for perturbations
IF (LFLAGS(1).EQ.1 .OR. LFLAGS(1).EQ.2) THEN
C *STATIC
FORCE = AK*(U(4)-U(1))
DFORCE = AK*(DU(4,1)-DU(1,1))
SRESID(1) = -DFORCE
SRESID(4) = DFORCE
RHS(1,1) = RHS(1,1)-SRESID(1)
RHS(4,1) = RHS(4,1)-SRESID(4)
ENERGY(2) = HALF*FORCE*(DU(4,1)-DU(1,1))
* + HALF*DFORCE*(U(4)-U(1))
* + HALF*DFORCE*(DU(4,1)-DU(1,1))
DO KVAR = 1, NSVARS
SVARS(KVAR) = ZERO
END DO
SVARS(1) = RHS(1,1)
SVARS(4) = RHS(4,1)
ELSE IF (LFLAGS(1).EQ.41) THEN
C *FREQUENCY
DO KRHS = 1, NRHS
DFORCE = AK*(DU(4,KRHS)-DU(1,KRHS))
SRESID(1) = -DFORCE
SRESID(4) = DFORCE
RHS(1,KRHS) = RHS(1,KRHS)-SRESID(1)
RHS(4,KRHS) = RHS(4,KRHS)-SRESID(4)
END DO
DO KVAR = 1, NSVARS
SVARS(KVAR) = ZERO
END DO
SVARS(1) = RHS(1,1)
SVARS(4) = RHS(4,1)
END IF
END IF
C
RETURN
END

View file

@ -0,0 +1,367 @@
c***********************************************************
subroutine uelmat(rhs,amatrx,svars,energy,ndofel,nrhs,
1 nsvars,props,nprops,coords,mcrd,nnode,u,du,
2 v,a,jtype,time,dtime,kstep,kinc,jelem,params,
3 ndload,jdltyp,adlmag,predef,npredf,lflags,mlvarx,
4 ddlmag,mdload,pnewdt,jprops,njpro,period,
5 materiallib)
c
include 'aba_param.inc'
C
dimension rhs(mlvarx,*), amatrx(ndofel, ndofel), props(*),
1 svars(*), energy(*), coords(mcrd, nnode), u(ndofel),
2 du(mlvarx,*), v(ndofel), a(ndofel), time(2), params(*),
3 jdltyp(mdload,*), adlmag(mdload,*), ddlmag(mdload,*),
4 predef(2, npredf, nnode), lflags(*), jprops(*)
parameter (zero=0.d0, dmone=-1.0d0, one=1.d0, four=4.0d0,
1 fourth=0.25d0,gaussCoord=0.577350269d0)
parameter (ndim=2, ndof=2, nshr=1,nnodemax=4,
1 ntens=4, ninpt=4, nsvint=4)
c
c ndim ... number of spatial dimensions
c ndof ... number of degrees of freedom per node
c nshr ... number of shear stress component
c ntens ... total number of stress tensor components
c (=ndi+nshr)
c ninpt ... number of integration points
c nsvint... number of state variables per integration pt
c (strain)
c
dimension stiff(ndof*nnodemax,ndof*nnodemax),
1 force(ndof*nnodemax), shape(nnodemax), dshape(ndim,nnodemax),
2 xjac(ndim,ndim),xjaci(ndim,ndim), bmat(nnodemax*ndim),
3 statevLocal(nsvint),stress(ntens), ddsdde(ntens, ntens),
4 stran(ntens), dstran(ntens), wght(ninpt)
c
dimension predef_loc(npredf),dpredef_loc(npredf),
1 defGrad(3,3),utmp(3),xdu(3),stiff_p(3,3),force_p(3)
dimension coord24(2,4),coords_ip(3)
data coord24 /dmone, dmone,
2 one, dmone,
3 one, one,
4 dmone, one/
c
data wght /one, one, one, one/
c
c*************************************************************
c
c U1 = first-order, plane strain, full integration
c
c State variables: each integration point has nsvint SDVs
c
c isvinc=(npt-1)*nsvint ... integration point counter
c statev(1+isvinc ) ... strain
c
c*************************************************************
if (lflags(3).eq.4) then
do i=1, ndofel
do j=1, ndofel
amatrx(i,j) = zero
end do
amatrx(i,i) = one
end do
goto 999
end if
c
c PRELIMINARIES
c
pnewdtLocal = pnewdt
if(jtype .ne. 1) then
write(7,*)'Incorrect element type'
call xit
endif
if(nsvars .lt. ninpt*nsvint) then
write(7,*)'Increase the number of SDVs to', ninpt*nsvint
call xit
endif
thickness = 0.1d0
c
c INITIALIZE RHS AND LHS
c
do k1=1, ndof*nnode
rhs(k1, 1)= zero
do k2=1, ndof*nnode
amatrx(k1, k2)= zero
end do
end do
c
c LOOP OVER INTEGRATION POINTS
c
do kintk = 1, ninpt
c
c EVALUATE SHAPE FUNCTIONS AND THEIR DERIVATIVES
c
c determine (g,h)
c
g = coord24(1,kintk)*gaussCoord
h = coord24(2,kintk)*gaussCoord
c
c shape functions
shape(1) = (one - g)*(one - h)/four;
shape(2) = (one + g)*(one - h)/four;
shape(3) = (one + g)*(one + h)/four;
shape(4) = (one - g)*(one + h)/four;
c
c derivative d(Ni)/d(g)
dshape(1,1) = -(one - h)/four;
dshape(1,2) = (one - h)/four;
dshape(1,3) = (one + h)/four;
dshape(1,4) = -(one + h)/four;
c
c derivative d(Ni)/d(h)
dshape(2,1) = -(one - g)/four;
dshape(2,2) = -(one + g)/four;
dshape(2,3) = (one + g)/four;
dshape(2,4) = (one - g)/four;
c
c compute coordinates at the integration point
c
do k1=1, 3
coords_ip(k1) = zero
end do
do k1=1,nnode
do k2=1,mcrd
coords_ip(k2)=coords_ip(k2)+shape(k1)*coords(k2,k1)
end do
end do
c
c INTERPOLATE FIELD VARIABLES
c
if(npredf.gt.0) then
do k1=1,npredf
predef_loc(k1) = zero
dpredef_loc(k1) = zero
do k2=1,nnode
predef_loc(k1) =
& predef_loc(k1)+
& (predef(1,k1,k2)-predef(2,k1,k2))*shape(k2)
dpredef_loc(k1) =
& dpredef_loc(k1)+predef(2,k1,k2)*shape(k2)
end do
end do
end if
c
c FORM B-MATRIX
c
djac = one
c
do i = 1, ndim
do j = 1, ndim
xjac(i,j) = zero
xjaci(i,j) = zero
end do
end do
c
do inod= 1, nnode
do idim = 1, ndim
do jdim = 1, ndim
xjac(jdim,idim) = xjac(jdim,idim) +
1 dshape(jdim,inod)*coords(idim,inod)
end do
end do
end do
djac = xjac(1,1)*xjac(2,2) - xjac(1,2)*xjac(2,1)
if (djac .gt. zero) then
! jacobian is positive - o.k.
xjaci(1,1) = xjac(2,2)/djac
xjaci(2,2) = xjac(1,1)/djac
xjaci(1,2) = -xjac(1,2)/djac
xjaci(2,1) = -xjac(2,1)/djac
else
! negative or zero jacobian
write(7,*)'WARNING: element',jelem,'has neg.
1 Jacobian'
pnewdt = fourth
endif
if (pnewdt .lt. pnewdtLocal) pnewdtLocal = pnewdt
c
do i = 1, nnode*ndim
bmat(i) = zero
end do
do inod = 1, nnode
do ider = 1, ndim
do idim = 1, ndim
irow = idim + (inod - 1)*ndim
bmat(irow) = bmat(irow) +
1 xjaci(idim,ider)*dshape(ider,inod)
end do
end do
end do
c
c CALCULATE INCREMENTAL STRAINS
c
do i = 1, ntens
dstran(i) = zero
end do
!
! set deformation gradient to Identity matrix
do k1=1,3
do k2=1,3
defGrad(k1,k2) = zero
end do
defGrad(k1,k1) = one
end do
c
c COMPUTE INCREMENTAL STRAINS
c
do nodi = 1, nnode
incr_row = (nodi - 1)*ndof
do i = 1, ndof
xdu(i)= du(i + incr_row,1)
utmp(i) = u(i + incr_row)
end do
dNidx = bmat(1 + (nodi-1)*ndim)
dNidy = bmat(2 + (nodi-1)*ndim)
dstran(1) = dstran(1) + dNidx*xdu(1)
dstran(2) = dstran(2) + dNidy*xdu(2)
dstran(4) = dstran(4) +
1 dNidy*xdu(1) +
2 dNidx*xdu(2)
c deformation gradient
defGrad(1,1) = defGrad(1,1) + dNidx*utmp(1)
defGrad(1,2) = defGrad(1,2) + dNidy*utmp(1)
defGrad(2,1) = defGrad(2,1) + dNidx*utmp(2)
defGrad(2,2) = defGrad(2,2) + dNidy*utmp(2)
end do
c
c CALL CONSTITUTIVE ROUTINE
c
isvinc= (kintk-1)*nsvint ! integration point increment
c
c prepare arrays for entry into material routines
c
do i = 1, nsvint
statevLocal(i)=svars(i+isvinc)
end do
c
c state variables
c
do k1=1,ntens
stran(k1) = statevLocal(k1)
stress(k1) = zero
end do
c
do i=1, ntens
do j=1, ntens
ddsdde(i,j) = zero
end do
ddsdde(i,j) = one
enddo
c
c compute characteristic element length
c
celent = sqrt(djac*dble(ninpt))
dvmat = djac*thickness
c
dvdv0 = one
call material_lib_mech(materiallib,stress,ddsdde,
1 stran,dstran,kintk,dvdv0,dvmat,defGrad,
2 predef_loc,dpredef_loc,npredf,celent,coords_ip)
c
do k1=1,ntens
statevLocal(k1) = stran(k1) + dstran(k1)
end do
c
isvinc= (kintk-1)*nsvint ! integration point increment
c
c update element state variables
c
do i = 1, nsvint
svars(i+isvinc)=statevLocal(i)
end do
c
c form stiffness matrix and internal force vector
c
dNjdx = zero
dNjdy = zero
do i = 1, ndof*nnode
force(i) = zero
do j = 1, ndof*nnode
stiff(j,i) = zero
end do
end do
dvol= wght(kintk)*djac
do nodj = 1, nnode
incr_col = (nodj - 1)*ndof
dNjdx = bmat(1+(nodj-1)*ndim)
dNjdy = bmat(2+(nodj-1)*ndim)
force_p(1) = dNjdx*stress(1) + dNjdy*stress(4)
force_p(2) = dNjdy*stress(2) + dNjdx*stress(4)
do jdof = 1, ndof
jcol = jdof + incr_col
force(jcol) = force(jcol) +
& force_p(jdof)*dvol
end do
do nodi = 1, nnode
incr_row = (nodi -1)*ndof
dNidx = bmat(1+(nodi-1)*ndim)
dNidy = bmat(2+(nodi-1)*ndim)
stiff_p(1,1) = dNidx*ddsdde(1,1)*dNjdx
& + dNidy*ddsdde(4,4)*dNjdy
& + dNidx*ddsdde(1,4)*dNjdy
& + dNidy*ddsdde(4,1)*dNjdx
stiff_p(1,2) = dNidx*ddsdde(1,2)*dNjdy
& + dNidy*ddsdde(4,4)*dNjdx
& + dNidx*ddsdde(1,4)*dNjdx
& + dNidy*ddsdde(4,2)*dNjdy
stiff_p(2,1) = dNidy*ddsdde(2,1)*dNjdx
& + dNidx*ddsdde(4,4)*dNjdy
& + dNidy*ddsdde(2,4)*dNjdy
& + dNidx*ddsdde(4,1)*dNjdx
stiff_p(2,2) = dNidy*ddsdde(2,2)*dNjdy
& + dNidx*ddsdde(4,4)*dNjdx
& + dNidy*ddsdde(2,4)*dNjdx
& + dNidx*ddsdde(4,2)*dNjdy
do jdof = 1, ndof
icol = jdof + incr_col
do idof = 1, ndof
irow = idof + incr_row
stiff(irow,icol) = stiff(irow,icol) +
& stiff_p(idof,jdof)*dvol
end do
end do
end do
end do
c
c assemble rhs and lhs
c
do k1=1, ndof*nnode
rhs(k1, 1) = rhs(k1, 1) - force(k1)
do k2=1, ndof*nnode
amatrx(k1, k2) = amatrx(k1, k2) + stiff(k1,k2)
end do
end do
end do ! end loop on material integration points
pnewdt = pnewdtLocal
c
999 continue
c
return
end

View file

@ -0,0 +1,367 @@
c***********************************************************
subroutine uelmat(rhs,amatrx,svars,energy,ndofel,nrhs,
1 nsvars,props,nprops,coords,mcrd,nnode,u,du,
2 v,a,jtype,time,dtime,kstep,kinc,jelem,params,
3 ndload,jdltyp,adlmag,predef,npredf,lflags,mlvarx,
4 ddlmag,mdload,pnewdt,jprops,njpro,period,
5 materiallib)
c
include 'aba_param.inc'
C
dimension rhs(mlvarx,*), amatrx(ndofel, ndofel), props(*),
1 svars(*), energy(*), coords(mcrd, nnode), u(ndofel),
2 du(mlvarx,*), v(ndofel), a(ndofel), time(2), params(*),
3 jdltyp(mdload,*), adlmag(mdload,*), ddlmag(mdload,*),
4 predef(2, npredf, nnode), lflags(*), jprops(*)
parameter (zero=0.d0, dmone=-1.0d0, one=1.d0, four=4.0d0,
1 fourth=0.25d0,gaussCoord=0.577350269d0)
parameter (ndim=2, ndof=2, nshr=1,nnodemax=4,
1 ntens=4, ninpt=4, nsvint=4)
c
c ndim ... number of spatial dimensions
c ndof ... number of degrees of freedom per node
c nshr ... number of shear stress component
c ntens ... total number of stress tensor components
c (=ndi+nshr)
c ninpt ... number of integration points
c nsvint... number of state variables per integration pt
c (strain)
c
dimension stiff(ndof*nnodemax,ndof*nnodemax),
1 force(ndof*nnodemax), shape(nnodemax), dshape(ndim,nnodemax),
2 xjac(ndim,ndim),xjaci(ndim,ndim), bmat(nnodemax*ndim),
3 statevLocal(nsvint),stress(ntens), ddsdde(ntens, ntens),
4 stran(ntens), dstran(ntens), wght(ninpt)
c
dimension predef_loc(npredf),dpredef_loc(npredf),
1 defGrad(3,3),utmp(3),xdu(3),stiff_p(3,3),force_p(3)
dimension coord24(2,4),coords_ip(3)
data coord24 /dmone, dmone,
2 one, dmone,
3 one, one,
4 dmone, one/
c
data wght /one, one, one, one/
c
c*************************************************************
c
c U1 = first-order, plane strain, full integration
c
c State variables: each integration point has nsvint SDVs
c
c isvinc=(npt-1)*nsvint ... integration point counter
c statev(1+isvinc ) ... strain
c
c*************************************************************
if (lflags(3).eq.4) then
do i=1, ndofel
do j=1, ndofel
amatrx(i,j) = zero
end do
amatrx(i,i) = one
end do
goto 999
end if
c
c PRELIMINARIES
c
pnewdtLocal = pnewdt
if(jtype .ne. 1) then
write(7,*)'Incorrect element type'
call xit
endif
if(nsvars .lt. ninpt*nsvint) then
write(7,*)'Increase the number of SDVs to', ninpt*nsvint
call xit
endif
thickness = 0.1d0
c
c INITIALIZE RHS AND LHS
c
do k1=1, ndof*nnode
rhs(k1, 1)= zero
do k2=1, ndof*nnode
amatrx(k1, k2)= zero
end do
end do
c
c LOOP OVER INTEGRATION POINTS
c
do kintk = 1, ninpt
c
c EVALUATE SHAPE FUNCTIONS AND THEIR DERIVATIVES
c
c determine (g,h)
c
g = coord24(1,kintk)*gaussCoord
h = coord24(2,kintk)*gaussCoord
c
c shape functions
shape(1) = (one - g)*(one - h)/four;
shape(2) = (one + g)*(one - h)/four;
shape(3) = (one + g)*(one + h)/four;
shape(4) = (one - g)*(one + h)/four;
c
c derivative d(Ni)/d(g)
dshape(1,1) = -(one - h)/four;
dshape(1,2) = (one - h)/four;
dshape(1,3) = (one + h)/four;
dshape(1,4) = -(one + h)/four;
c
c derivative d(Ni)/d(h)
dshape(2,1) = -(one - g)/four;
dshape(2,2) = -(one + g)/four;
dshape(2,3) = (one + g)/four;
dshape(2,4) = (one - g)/four;
c
c compute coordinates at the integration point
c
do k1=1, 3
coords_ip(k1) = zero
end do
do k1=1,nnode
do k2=1,mcrd
coords_ip(k2)=coords_ip(k2)+shape(k1)*coords(k2,k1)
end do
end do
c
c INTERPOLATE FIELD VARIABLES
c
if(npredf.gt.0) then
do k1=1,npredf
predef_loc(k1) = zero
dpredef_loc(k1) = zero
do k2=1,nnode
predef_loc(k1) =
& predef_loc(k1)+
& (predef(1,k1,k2)-predef(2,k1,k2))*shape(k2)
dpredef_loc(k1) =
& dpredef_loc(k1)+predef(2,k1,k2)*shape(k2)
end do
end do
end if
c
c FORM B-MATRIX
c
djac = one
c
do i = 1, ndim
do j = 1, ndim
xjac(i,j) = zero
xjaci(i,j) = zero
end do
end do
c
do inod= 1, nnode
do idim = 1, ndim
do jdim = 1, ndim
xjac(jdim,idim) = xjac(jdim,idim) +
1 dshape(jdim,inod)*coords(idim,inod)
end do
end do
end do
djac = xjac(1,1)*xjac(2,2) - xjac(1,2)*xjac(2,1)
if (djac .gt. zero) then
! jacobian is positive - o.k.
xjaci(1,1) = xjac(2,2)/djac
xjaci(2,2) = xjac(1,1)/djac
xjaci(1,2) = -xjac(1,2)/djac
xjaci(2,1) = -xjac(2,1)/djac
else
! negative or zero jacobian
write(7,*)'WARNING: element',jelem,'has neg.
1 Jacobian'
pnewdt = fourth
endif
if (pnewdt .lt. pnewdtLocal) pnewdtLocal = pnewdt
c
do i = 1, nnode*ndim
bmat(i) = zero
end do
do inod = 1, nnode
do ider = 1, ndim
do idim = 1, ndim
irow = idim + (inod - 1)*ndim
bmat(irow) = bmat(irow) +
1 xjaci(idim,ider)*dshape(ider,inod)
end do
end do
end do
c
c CALCULATE INCREMENTAL STRAINS
c
do i = 1, ntens
dstran(i) = zero
end do
!
! set deformation gradient to Identity matrix
do k1=1,3
do k2=1,3
defGrad(k1,k2) = zero
end do
defGrad(k1,k1) = one
end do
c
c COMPUTE INCREMENTAL STRAINS
c
do nodi = 1, nnode
incr_row = (nodi - 1)*ndof
do i = 1, ndof
xdu(i)= du(i + incr_row,1)
utmp(i) = u(i + incr_row)
end do
dNidx = bmat(1 + (nodi-1)*ndim)
dNidy = bmat(2 + (nodi-1)*ndim)
dstran(1) = dstran(1) + dNidx*xdu(1)
dstran(2) = dstran(2) + dNidy*xdu(2)
dstran(4) = dstran(4) +
1 dNidy*xdu(1) +
2 dNidx*xdu(2)
c deformation gradient
defGrad(1,1) = defGrad(1,1) + dNidx*utmp(1)
defGrad(1,2) = defGrad(1,2) + dNidy*utmp(1)
defGrad(2,1) = defGrad(2,1) + dNidx*utmp(2)
defGrad(2,2) = defGrad(2,2) + dNidy*utmp(2)
end do
c
c CALL CONSTITUTIVE ROUTINE
c
isvinc= (kintk-1)*nsvint ! integration point increment
c
c prepare arrays for entry into material routines
c
do i = 1, nsvint
statevLocal(i)=svars(i+isvinc)
end do
c
c state variables
c
do k1=1,ntens
stran(k1) = statevLocal(k1)
stress(k1) = zero
end do
c
do i=1, ntens
do j=1, ntens
ddsdde(i,j) = zero
end do
ddsdde(i,j) = one
enddo
c
c compute characteristic element length
c
celent = sqrt(djac*dble(ninpt))
dvmat = djac*thickness
c
dvdv0 = one
call material_lib_mech(materiallib,stress,ddsdde,
1 stran,dstran,kintk,dvdv0,dvmat,defGrad,
2 predef_loc,dpredef_loc,npredf,celent,coords_ip)
c
do k1=1,ntens
statevLocal(k1) = stran(k1) + dstran(k1)
end do
c
isvinc= (kintk-1)*nsvint ! integration point increment
c
c update element state variables
c
do i = 1, nsvint
svars(i+isvinc)=statevLocal(i)
end do
c
c form stiffness matrix and internal force vector
c
dNjdx = zero
dNjdy = zero
do i = 1, ndof*nnode
force(i) = zero
do j = 1, ndof*nnode
stiff(j,i) = zero
end do
end do
dvol= wght(kintk)*djac
do nodj = 1, nnode
incr_col = (nodj - 1)*ndof
dNjdx = bmat(1+(nodj-1)*ndim)
dNjdy = bmat(2+(nodj-1)*ndim)
force_p(1) = dNjdx*stress(1) + dNjdy*stress(4)
force_p(2) = dNjdy*stress(2) + dNjdx*stress(4)
do jdof = 1, ndof
jcol = jdof + incr_col
force(jcol) = force(jcol) +
& force_p(jdof)*dvol
end do
do nodi = 1, nnode
incr_row = (nodi -1)*ndof
dNidx = bmat(1+(nodi-1)*ndim)
dNidy = bmat(2+(nodi-1)*ndim)
stiff_p(1,1) = dNidx*ddsdde(1,1)*dNjdx
& + dNidy*ddsdde(4,4)*dNjdy
& + dNidx*ddsdde(1,4)*dNjdy
& + dNidy*ddsdde(4,1)*dNjdx
stiff_p(1,2) = dNidx*ddsdde(1,2)*dNjdy
& + dNidy*ddsdde(4,4)*dNjdx
& + dNidx*ddsdde(1,4)*dNjdx
& + dNidy*ddsdde(4,2)*dNjdy
stiff_p(2,1) = dNidy*ddsdde(2,1)*dNjdx
& + dNidx*ddsdde(4,4)*dNjdy
& + dNidy*ddsdde(2,4)*dNjdy
& + dNidx*ddsdde(4,1)*dNjdx
stiff_p(2,2) = dNidy*ddsdde(2,2)*dNjdy
& + dNidx*ddsdde(4,4)*dNjdx
& + dNidy*ddsdde(2,4)*dNjdx
& + dNidx*ddsdde(4,2)*dNjdy
do jdof = 1, ndof
icol = jdof + incr_col
do idof = 1, ndof
irow = idof + incr_row
stiff(irow,icol) = stiff(irow,icol) +
& stiff_p(idof,jdof)*dvol
end do
end do
end do
end do
c
c assemble rhs and lhs
c
do k1=1, ndof*nnode
rhs(k1, 1) = rhs(k1, 1) - force(k1)
do k2=1, ndof*nnode
amatrx(k1, k2) = amatrx(k1, k2) + stiff(k1,k2)
end do
end do
end do ! end loop on material integration points
pnewdt = pnewdtLocal
c
999 continue
c
return
end

View file

@ -0,0 +1,367 @@
c***********************************************************
subroutine uelmat(rhs,amatrx,svars,energy,ndofel,nrhs,
1 nsvars,props,nprops,coords,mcrd,nnode,u,du,
2 v,a,jtype,time,dtime,kstep,kinc,jelem,params,
3 ndload,jdltyp,adlmag,predef,npredf,lflags,mlvarx,
4 ddlmag,mdload,pnewdt,jprops,njpro,period,
5 materiallib)
c
include 'aba_param.inc'
C
dimension rhs(mlvarx,*), amatrx(ndofel, ndofel), props(*),
1 svars(*), energy(*), coords(mcrd, nnode), u(ndofel),
2 du(mlvarx,*), v(ndofel), a(ndofel), time(2), params(*),
3 jdltyp(mdload,*), adlmag(mdload,*), ddlmag(mdload,*),
4 predef(2, npredf, nnode), lflags(*), jprops(*)
parameter (zero=0.d0, dmone=-1.0d0, one=1.d0, four=4.0d0,
1 fourth=0.25d0,gaussCoord=0.577350269d0)
parameter (ndim=2, ndof=2, nshr=1,nnodemax=4,
1 ntens=4, ninpt=4, nsvint=4)
c
c ndim ... number of spatial dimensions
c ndof ... number of degrees of freedom per node
c nshr ... number of shear stress component
c ntens ... total number of stress tensor components
c (=ndi+nshr)
c ninpt ... number of integration points
c nsvint... number of state variables per integration pt
c (strain)
c
dimension stiff(ndof*nnodemax,ndof*nnodemax),
1 force(ndof*nnodemax), shape(nnodemax), dshape(ndim,nnodemax),
2 xjac(ndim,ndim),xjaci(ndim,ndim), bmat(nnodemax*ndim),
3 statevLocal(nsvint),stress(ntens), ddsdde(ntens, ntens),
4 stran(ntens), dstran(ntens), wght(ninpt)
c
dimension predef_loc(npredf),dpredef_loc(npredf),
1 defGrad(3,3),utmp(3),xdu(3),stiff_p(3,3),force_p(3)
dimension coord24(2,4),coords_ip(3)
data coord24 /dmone, dmone,
2 one, dmone,
3 one, one,
4 dmone, one/
c
data wght /one, one, one, one/
c
c*************************************************************
c
c U1 = first-order, plane strain, full integration
c
c State variables: each integration point has nsvint SDVs
c
c isvinc=(npt-1)*nsvint ... integration point counter
c statev(1+isvinc ) ... strain
c
c*************************************************************
if (lflags(3).eq.4) then
do i=1, ndofel
do j=1, ndofel
amatrx(i,j) = zero
end do
amatrx(i,i) = one
end do
goto 999
end if
c
c PRELIMINARIES
c
pnewdtLocal = pnewdt
if(jtype .ne. 1) then
write(7,*)'Incorrect element type'
call xit
endif
if(nsvars .lt. ninpt*nsvint) then
write(7,*)'Increase the number of SDVs to', ninpt*nsvint
call xit
endif
thickness = 0.1d0
c
c INITIALIZE RHS AND LHS
c
do k1=1, ndof*nnode
rhs(k1, 1)= zero
do k2=1, ndof*nnode
amatrx(k1, k2)= zero
end do
end do
c
c LOOP OVER INTEGRATION POINTS
c
do kintk = 1, ninpt
c
c EVALUATE SHAPE FUNCTIONS AND THEIR DERIVATIVES
c
c determine (g,h)
c
g = coord24(1,kintk)*gaussCoord
h = coord24(2,kintk)*gaussCoord
c
c shape functions
shape(1) = (one - g)*(one - h)/four;
shape(2) = (one + g)*(one - h)/four;
shape(3) = (one + g)*(one + h)/four;
shape(4) = (one - g)*(one + h)/four;
c
c derivative d(Ni)/d(g)
dshape(1,1) = -(one - h)/four;
dshape(1,2) = (one - h)/four;
dshape(1,3) = (one + h)/four;
dshape(1,4) = -(one + h)/four;
c
c derivative d(Ni)/d(h)
dshape(2,1) = -(one - g)/four;
dshape(2,2) = -(one + g)/four;
dshape(2,3) = (one + g)/four;
dshape(2,4) = (one - g)/four;
c
c compute coordinates at the integration point
c
do k1=1, 3
coords_ip(k1) = zero
end do
do k1=1,nnode
do k2=1,mcrd
coords_ip(k2)=coords_ip(k2)+shape(k1)*coords(k2,k1)
end do
end do
c
c INTERPOLATE FIELD VARIABLES
c
if(npredf.gt.0) then
do k1=1,npredf
predef_loc(k1) = zero
dpredef_loc(k1) = zero
do k2=1,nnode
predef_loc(k1) =
& predef_loc(k1)+
& (predef(1,k1,k2)-predef(2,k1,k2))*shape(k2)
dpredef_loc(k1) =
& dpredef_loc(k1)+predef(2,k1,k2)*shape(k2)
end do
end do
end if
c
c FORM B-MATRIX
c
djac = one
c
do i = 1, ndim
do j = 1, ndim
xjac(i,j) = zero
xjaci(i,j) = zero
end do
end do
c
do inod= 1, nnode
do idim = 1, ndim
do jdim = 1, ndim
xjac(jdim,idim) = xjac(jdim,idim) +
1 dshape(jdim,inod)*coords(idim,inod)
end do
end do
end do
djac = xjac(1,1)*xjac(2,2) - xjac(1,2)*xjac(2,1)
if (djac .gt. zero) then
! jacobian is positive - o.k.
xjaci(1,1) = xjac(2,2)/djac
xjaci(2,2) = xjac(1,1)/djac
xjaci(1,2) = -xjac(1,2)/djac
xjaci(2,1) = -xjac(2,1)/djac
else
! negative or zero jacobian
write(7,*)'WARNING: element',jelem,'has neg.
1 Jacobian'
pnewdt = fourth
endif
if (pnewdt .lt. pnewdtLocal) pnewdtLocal = pnewdt
c
do i = 1, nnode*ndim
bmat(i) = zero
end do
do inod = 1, nnode
do ider = 1, ndim
do idim = 1, ndim
irow = idim + (inod - 1)*ndim
bmat(irow) = bmat(irow) +
1 xjaci(idim,ider)*dshape(ider,inod)
end do
end do
end do
c
c CALCULATE INCREMENTAL STRAINS
c
do i = 1, ntens
dstran(i) = zero
end do
!
! set deformation gradient to Identity matrix
do k1=1,3
do k2=1,3
defGrad(k1,k2) = zero
end do
defGrad(k1,k1) = one
end do
c
c COMPUTE INCREMENTAL STRAINS
c
do nodi = 1, nnode
incr_row = (nodi - 1)*ndof
do i = 1, ndof
xdu(i)= du(i + incr_row,1)
utmp(i) = u(i + incr_row)
end do
dNidx = bmat(1 + (nodi-1)*ndim)
dNidy = bmat(2 + (nodi-1)*ndim)
dstran(1) = dstran(1) + dNidx*xdu(1)
dstran(2) = dstran(2) + dNidy*xdu(2)
dstran(4) = dstran(4) +
1 dNidy*xdu(1) +
2 dNidx*xdu(2)
c deformation gradient
defGrad(1,1) = defGrad(1,1) + dNidx*utmp(1)
defGrad(1,2) = defGrad(1,2) + dNidy*utmp(1)
defGrad(2,1) = defGrad(2,1) + dNidx*utmp(2)
defGrad(2,2) = defGrad(2,2) + dNidy*utmp(2)
end do
c
c CALL CONSTITUTIVE ROUTINE
c
isvinc= (kintk-1)*nsvint ! integration point increment
c
c prepare arrays for entry into material routines
c
do i = 1, nsvint
statevLocal(i)=svars(i+isvinc)
end do
c
c state variables
c
do k1=1,ntens
stran(k1) = statevLocal(k1)
stress(k1) = zero
end do
c
do i=1, ntens
do j=1, ntens
ddsdde(i,j) = zero
end do
ddsdde(i,j) = one
enddo
c
c compute characteristic element length
c
celent = sqrt(djac*dble(ninpt))
dvmat = djac*thickness
c
dvdv0 = one
call material_lib_mech(materiallib,stress,ddsdde,
1 stran,dstran,kintk,dvdv0,dvmat,defGrad,
2 predef_loc,dpredef_loc,npredf,celent,coords_ip)
c
do k1=1,ntens
statevLocal(k1) = stran(k1) + dstran(k1)
end do
c
isvinc= (kintk-1)*nsvint ! integration point increment
c
c update element state variables
c
do i = 1, nsvint
svars(i+isvinc)=statevLocal(i)
end do
c
c form stiffness matrix and internal force vector
c
dNjdx = zero
dNjdy = zero
do i = 1, ndof*nnode
force(i) = zero
do j = 1, ndof*nnode
stiff(j,i) = zero
end do
end do
dvol= wght(kintk)*djac
do nodj = 1, nnode
incr_col = (nodj - 1)*ndof
dNjdx = bmat(1+(nodj-1)*ndim)
dNjdy = bmat(2+(nodj-1)*ndim)
force_p(1) = dNjdx*stress(1) + dNjdy*stress(4)
force_p(2) = dNjdy*stress(2) + dNjdx*stress(4)
do jdof = 1, ndof
jcol = jdof + incr_col
force(jcol) = force(jcol) +
& force_p(jdof)*dvol
end do
do nodi = 1, nnode
incr_row = (nodi -1)*ndof
dNidx = bmat(1+(nodi-1)*ndim)
dNidy = bmat(2+(nodi-1)*ndim)
stiff_p(1,1) = dNidx*ddsdde(1,1)*dNjdx
& + dNidy*ddsdde(4,4)*dNjdy
& + dNidx*ddsdde(1,4)*dNjdy
& + dNidy*ddsdde(4,1)*dNjdx
stiff_p(1,2) = dNidx*ddsdde(1,2)*dNjdy
& + dNidy*ddsdde(4,4)*dNjdx
& + dNidx*ddsdde(1,4)*dNjdx
& + dNidy*ddsdde(4,2)*dNjdy
stiff_p(2,1) = dNidy*ddsdde(2,1)*dNjdx
& + dNidx*ddsdde(4,4)*dNjdy
& + dNidy*ddsdde(2,4)*dNjdy
& + dNidx*ddsdde(4,1)*dNjdx
stiff_p(2,2) = dNidy*ddsdde(2,2)*dNjdy
& + dNidx*ddsdde(4,4)*dNjdx
& + dNidy*ddsdde(2,4)*dNjdx
& + dNidx*ddsdde(4,2)*dNjdy
do jdof = 1, ndof
icol = jdof + incr_col
do idof = 1, ndof
irow = idof + incr_row
stiff(irow,icol) = stiff(irow,icol) +
& stiff_p(idof,jdof)*dvol
end do
end do
end do
end do
c
c assemble rhs and lhs
c
do k1=1, ndof*nnode
rhs(k1, 1) = rhs(k1, 1) - force(k1)
do k2=1, ndof*nnode
amatrx(k1, k2) = amatrx(k1, k2) + stiff(k1,k2)
end do
end do
end do ! end loop on material integration points
pnewdt = pnewdtLocal
c
999 continue
c
return
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

View file

@ -0,0 +1,53 @@
C USER INPUT FOR ADAPTIVE MESH CONSTRAINT
C
SUBROUTINE UMESHMOTION(UREF,ULOCAL,NODE,NNDOF,
$ LNODETYPE,ALOCAL,NDIM,TIME,DTIME,PNEWDT,
$ KSTEP,KINC,KMESHSWEEP,JMATYP,JGVBLOCK,LSMOOTH)
C
include 'ABA_PARAM.INC'
C
C USER DEFINED DIMENSION STATEMENTS
C
CHARACTER*80 PARTNAME
DIMENSION ARRAY(1000),JPOS(15),HFARRAY(1000)
DIMENSION ULOCAL(*),UGLOBAL(NDIM),TLOCAL(NDIM)
DIMENSION JGVBLOCK(*),JMATYP(*)
DIMENSION NODELIST(100),JELEMLIST(10),JELEMTYPE(10)
DIMENSION ALOCAL(NDIM,*)
DIMENSION UTEMP(2)
C
C The dimensions of the variables ARRAY and JARRAY
C must be set equal to or greater than 15
C
CALL GETPARTINFO(NODE,0,PARTNAME,LOCNUM,JRCD)
CALL GETVRN(LOCNUM,'COORD',ARRAY,JRCD,JGVBLOCK,LTRN)
NELEMS=10
CALL GETNODETOELEMCONN(NODE, NELEMS, JELEMLIST, JELEMTYPE,
$ JRCD, JGVBLOCK)
CALL GETVRMAVGATNODE(NODE,1,'HFL',HFARRAY,JRCD,JELEMLIST,
$ NELEMS,JMATYP,JGVBLOCK)
C PRINT *,'****'
C PRINT *, HFARRAY(1),HFARRAY(2),HFARRAY(3),HFARRAY(4)
C PRINT *,NODE,TIME
FluxX=HFARRAY(2)
FluxY=HFARRAY(3)
FluxZ=HFARRAY(4)
if(abs(FluxX)<0.001)FluxX=0.
if(abs(FluxY)<0.001)FluxY=0.
if(abs(FluxZ)<0.001)FluxZ=0.
UGLOBAL(1) = -2.*FluxX
UGLOBAL(2) = -2.*FluxY
UGLOBAL(3) = 0.
DO I=1,NDIM
TLOCAL(I)=0.
DO J=1,NDIM
TLOCAL(I)=TLOCAL(I)+UGLOBAL(J)*ALOCAL(J,I)
ENDDO
ENDDO
DO I=1,NDIM
ULOCAL(I)=TLOCAL(I)
ENDDO
lsmooth=1
C
RETURN
END

View file

@ -0,0 +1,27 @@
c J. Grogan, 2012
c -------------------------------------------------------------------
SUBROUTINE USDFLD(FIELD,STATEV,PNEWDT,DIRECT,T,CELENT,
1 TIME,DTIME,CMNAME,ORNAME,NFIELD,NSTATV,NOEL,NPT,LAYER,
2 KSPT,KSTEP,KINC,NDI,NSHR,COORD,JMAC,JMATYP,MATLAYO,
3 LACCFLA)
C
INCLUDE 'ABA_PARAM.INC'
C
CHARACTER*80 CMNAME,ORNAME
CHARACTER*3 FLGRAY(15)
DIMENSION FIELD(NFIELD),STATEV(NSTATV),DIRECT(3,3),
1 T(3,3),TIME(2)
DIMENSION ARRAY(15),JARRAY(15),JMAC(*),JMATYP(*),
1 COORD(*)
c -------------------------------------------------------------------
field(1)=0.
return
end subroutine

View file

@ -0,0 +1,220 @@
c J. Grogan, 2012
c -------------------------------------------------------------------
SUBROUTINE USDFLD(FIELD,STATEV,PNEWDT,DIRECT,T,CELENT,
1 TIME,DTIME,CMNAME,ORNAME,NFIELD,NSTATV,NOEL,NPT,LAYER,
2 KSPT,KSTEP,KINC,NDI,NSHR,COORD,JMAC,JMATYP,MATLAYO,
3 LACCFLA)
C
INCLUDE 'ABA_PARAM.INC'
C
CHARACTER*80 CMNAME,ORNAME
CHARACTER*3 FLGRAY(15)
DIMENSION FIELD(NFIELD),STATEV(NSTATV),DIRECT(3,3),
1 T(3,3),TIME(2)
DIMENSION ARRAY(15),JARRAY(15),JMAC(*),JMATYP(*),
1 COORD(*)
c -------------------------------------------------------------------
field(1)=0.
print *, coord(1),time(1),dtime,T,'****'
return
end subroutine
SUBROUTINE UEL(RHS,AMATRX,SVARS,ENERGY,NDOFEL,NRHS,NSVARS,
1 PROPS,NPROPS,COORDS,MCRD,NNODE,U,DU,V,A,JTYPE,TIME,
2 DTIME,KSTEP,KINC,JELEM,PARAMS,NDLOAD,JDLTYP,ADLMAG,
3 PREDEF,NPREDF,LFLAGS,MLVARX,DDLMAG,MDLOAD,PNEWDT,
4 JPROPS,NJPROP,PERIOD)
C
INCLUDE 'ABA_PARAM.INC'
PARAMETER ( ZERO = 0.D0, HALF = 0.5D0, ONE = 1.D0 )
C
DIMENSION RHS(MLVARX,*),AMATRX(NDOFEL,NDOFEL),
1 SVARS(NSVARS),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(*),
5 JPROPS(*)
DIMENSION SRESID(6)
C
C UEL SUBROUTINE FOR A HORIZONTAL TRUSS ELEMENT
C
C SRESID - stores the static residual at time t+dt
C SVARS - In 1-6, contains the static residual at time t
C upon entering the routine. SRESID is copied to
C SVARS(1-6) after the dynamic residual has been
C calculated.
C - For half-increment residual calculations: In 7-12,
C contains the static residual at the beginning
C of the previous increment. SVARS(1-6) are copied
C into SVARS(7-12) after the dynamic residual has
C been calculated.
C
AREA = PROPS(1)
E = PROPS(2)
ANU = PROPS(3)
RHO = PROPS(4)
C
ALEN = ABS(COORDS(1,2)-COORDS(1,1))
AK = AREA*E/ALEN
AM = HALF*AREA*RHO*ALEN
C
DO K1 = 1, NDOFEL
SRESID(K1) = ZERO
DO KRHS = 1, NRHS
RHS(K1,KRHS) = ZERO
END DO
DO K2 = 1, NDOFEL
AMATRX(K2,K1) = ZERO
END DO
END DO
C
IF (LFLAGS(3).EQ.1) THEN
C Normal incrementation
IF (LFLAGS(1).EQ.1 .OR. LFLAGS(1).EQ.2) THEN
C *STATIC
AMATRX(1,1) = AK
AMATRX(4,4) = AK
AMATRX(1,4) = -AK
AMATRX(4,1) = -AK
IF (LFLAGS(4).NE.0) THEN
FORCE = AK*(U(4)-U(1))
DFORCE = AK*(DU(4,1)-DU(1,1))
SRESID(1) = -DFORCE
SRESID(4) = DFORCE
RHS(1,1) = RHS(1,1)-SRESID(1)
RHS(4,1) = RHS(4,1)-SRESID(4)
ENERGY(2) = HALF*FORCE*(DU(4,1)-DU(1,1))
* + HALF*DFORCE*(U(4)-U(1))
* + HALF*DFORCE*(DU(4,1)-DU(1,1))
ELSE
FORCE = AK*(U(4)-U(1))
SRESID(1) = -FORCE
SRESID(4) = FORCE
RHS(1,1) = RHS(1,1)-SRESID(1)
RHS(4,1) = RHS(4,1)-SRESID(4)
DO KDLOAD = 1, NDLOAD
IF (JDLTYP(KDLOAD,1).EQ.1001) THEN
RHS(4,1) = RHS(4,1)+ADLMAG(KDLOAD,1)
ENERGY(8) = ENERGY(8)+(ADLMAG(KDLOAD,1)
* - HALF*DDLMAG(KDLOAD,1))*DU(4,1)
IF (NRHS.EQ.2) THEN
C Riks
RHS(4,2) = RHS(4,2)+DDLMAG(KDLOAD,1)
END IF
END IF
END DO
ENERGY(2) = HALF*FORCE*(U(4)-U(1))
END IF
ELSE IF (LFLAGS(1).EQ.11 .OR. LFLAGS(1).EQ.12) THEN
C *DYNAMIC
ALPHA = PARAMS(1)
BETA = PARAMS(2)
GAMMA = PARAMS(3)
C
DADU = ONE/(BETA*DTIME**2)
DVDU = GAMMA/(BETA*DTIME)
C
DO K1 = 1, NDOFEL
AMATRX(K1,K1) = AM*DADU
RHS(K1,1) = RHS(K1,1)-AM*A(K1)
END DO
AMATRX(1,1) = AMATRX(1,1)+(ONE+ALPHA)*AK
AMATRX(4,4) = AMATRX(4,4)+(ONE+ALPHA)*AK
AMATRX(1,4) = AMATRX(1,4)-(ONE+ALPHA)*AK
AMATRX(4,1) = AMATRX(4,1)-(ONE+ALPHA)*AK
FORCE = AK*(U(4)-U(1))
SRESID(1) = -FORCE
SRESID(4) = FORCE
RHS(1,1) = RHS(1,1) -
* ((ONE+ALPHA)*SRESID(1)-ALPHA*SVARS(1))
RHS(4,1) = RHS(4,1) -
* ((ONE+ALPHA)*SRESID(4)-ALPHA*SVARS(4))
ENERGY(1) = ZERO
DO K1 = 1, NDOFEL
SVARS(K1+6) = SVARS(k1)
SVARS(K1) = SRESID(K1)
ENERGY(1) = ENERGY(1)+HALF*V(K1)*AM*V(K1)
END DO
ENERGY(2) = HALF*FORCE*(U(4)-U(1))
END IF
ELSE IF (LFLAGS(3).EQ.2) THEN
C Stiffness matrix
AMATRX(1,1) = AK
AMATRX(4,4) = AK
AMATRX(1,4) = -AK
AMATRX(4,1) = -AK
ELSE IF (LFLAGS(3).EQ.4) THEN
C Mass matrix
DO K1 = 1, NDOFEL
AMATRX(K1,K1) = AM
END DO
ELSE IF (LFLAGS(3).EQ.5) THEN
C Half-increment residual calculation
ALPHA = PARAMS(1)
FORCE = AK*(U(4)-U(1))
SRESID(1) = -FORCE
SRESID(4) = FORCE
RHS(1,1) = RHS(1,1)-AM*A(1)-(ONE+ALPHA)*SRESID(1)
* + HALF*ALPHA*( SVARS(1)+SVARS(7) )
RHS(4,1) = RHS(4,1)-AM*A(4)-(ONE+ALPHA)*SRESID(4)
* + HALF*ALPHA*( SVARS(4)+SVARS(10) )
ELSE IF (LFLAGS(3).EQ.6) THEN
C Initial acceleration calculation
DO K1 = 1, NDOFEL
AMATRX(K1,K1) = AM
END DO
FORCE = AK*(U(4)-U(1))
SRESID(1) = -FORCE
SRESID(4) = FORCE
RHS(1,1) = RHS(1,1)-SRESID(1)
RHS(4,1) = RHS(4,1)-SRESID(4)
ENERGY(1) = ZERO
DO K1 = 1, NDOFEL
SVARS(K1) = SRESID(K1)
ENERGY(1) = ENERGY(1)+HALF*V(K1)*AM*V(K1)
END DO
ENERGY(2) = HALF*FORCE*(U(4)-U(1))
ELSE IF (LFLAGS(3).EQ.100) THEN
C Output for perturbations
IF (LFLAGS(1).EQ.1 .OR. LFLAGS(1).EQ.2) THEN
C *STATIC
FORCE = AK*(U(4)-U(1))
DFORCE = AK*(DU(4,1)-DU(1,1))
SRESID(1) = -DFORCE
SRESID(4) = DFORCE
RHS(1,1) = RHS(1,1)-SRESID(1)
RHS(4,1) = RHS(4,1)-SRESID(4)
ENERGY(2) = HALF*FORCE*(DU(4,1)-DU(1,1))
* + HALF*DFORCE*(U(4)-U(1))
* + HALF*DFORCE*(DU(4,1)-DU(1,1))
DO KVAR = 1, NSVARS
SVARS(KVAR) = ZERO
END DO
SVARS(1) = RHS(1,1)
SVARS(4) = RHS(4,1)
ELSE IF (LFLAGS(1).EQ.41) THEN
C *FREQUENCY
DO KRHS = 1, NRHS
DFORCE = AK*(DU(4,KRHS)-DU(1,KRHS))
SRESID(1) = -DFORCE
SRESID(4) = DFORCE
RHS(1,KRHS) = RHS(1,KRHS)-SRESID(1)
RHS(4,KRHS) = RHS(4,KRHS)-SRESID(4)
END DO
DO KVAR = 1, NSVARS
SVARS(KVAR) = ZERO
END DO
SVARS(1) = RHS(1,1)
SVARS(4) = RHS(4,1)
END IF
END IF
C
RETURN
END

View file

@ -0,0 +1,154 @@
function [] = 2DSimp()
% MATLAB based 2-D XFEM Solver
% J. Grogan (2012)
clear all
% Define Mesh
NumX=3;
NumY=3;
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);
Element(index,4)=i+(NumX+1)*(j)+1;
end
end
numElem=(NumX)*(NumY);
% dofs per node
ndof=1;
% Define Section Properties
rho=1.;
% initial interface position
dpos=0.25;
% Initial temperatures
Tnew=zeros(numNodes,1);
Bound=zeros(numNodes,1);
stored(1)=dpos;
for e=1:numElem
for n=1:4
crdn=Node(Element(e,n),1);
if crdn<=dpos
Tnew(Element(e,n))=1.;
Bound(Element(e,n))=1.;
end
end
end
% Define Time Step
dtime=0.05;
tsteps=20;
time=0.;
% Loop through time steps
for ts=1:tsteps
K=zeros(numNodes*ndof,numNodes*ndof);
M=zeros(numNodes*ndof,numNodes*ndof);
% 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
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;
% 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=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
% 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)
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);
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,91 @@
*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, 0.2, 0., 0.
3, 0.4, 0., 0.
4, 0.6, 0., 0.
5, 0.8, 0., 0.
6, 1., 0., 0.
7, 1.2, 0., 0.
8, 1.4, 0., 0.
9, 1.6, 0., 0.
10, 1.8, 0., 0.
11, 2., 0., 0.
*USER ELEMENT,NODES=2,TYPE=U8008,PROP=1,COORDINATES=1,VAR=2,unsymm
11,12
*Element, type=U8008,ELSET=UEL
1, 1, 2
2, 2, 3
3, 3, 4
4, 4, 5
5, 5, 6
6, 6, 7
7, 7, 8
8, 8, 9
9, 9, 10
10, 10, 11
*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,
*Nset, nset=_PickedSet17, internal, instance=Part-1-1
2,
*Nset, nset=Set-6, instance=Part-1-1
1,
*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.6, 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,80 @@
function [] = FESolve()
% MATLAB based FE Solver
% J. Grogan (2012)
clear all
% Define Geometry
len=1.;
% Define Section Properties
rho=1.;
spec=1.;
cond=1.;
% Generate Mesh
numElem=10;
ndCoords=linspace(0,len,numElem+1);
numNodes=size(ndCoords,2);
indx=1:numElem;
elemNodes(:,1)=indx;
elemNodes(:,2)=indx+1;
% Initialize Conditions
Tnew=zeros(numNodes,1);
Tnew(1)=1.;
% Define Time Step
dtime=.1;
tsteps=10;
time=0.;
% Loop through time steps
for ts=1:tsteps;
time=time+dtime;
K=zeros(numNodes,numNodes);
M=zeros(numNodes,numNodes);
% Loop Through Elements
for e=1:numElem;
Ke=zeros(2);
Me=zeros(2);
gpx(1)=-1./sqrt(3.);
gpx(2)=1./sqrt(3.);
ajacob=abs(ndCoords(elemNodes(e,2))-ndCoords(elemNodes(e,1)))/2.;
% Loop Through Int Points
for i=1:2;
c=gpx(i);
phi(1)=(1.-c)/2.;
phi(2)=(1.+c)/2.;
phic(1)=-0.5;
phic(2)=0.5;
phix(1)=phic(1)/ajacob;
phix(2)=phic(2)/ajacob;
we=ajacob;
Ke=Ke+we*cond*phix'*phix;
Me=Me+(we*rho*spec*phi'*phi)/dtime;
end
% Assemble Global Matrices
K(elemNodes(e,1),elemNodes(e,1))=K(elemNodes(e,1),elemNodes(e,1))+Ke(1,1);
K(elemNodes(e,1),elemNodes(e,2))=K(elemNodes(e,1),elemNodes(e,2))+Ke(1,2);
K(elemNodes(e,2),elemNodes(e,1))=K(elemNodes(e,2),elemNodes(e,1))+Ke(2,1);
K(elemNodes(e,2),elemNodes(e,2))=K(elemNodes(e,2),elemNodes(e,2))+Ke(2,2);
M(elemNodes(e,1),elemNodes(e,1))=M(elemNodes(e,1),elemNodes(e,1))+Me(1,1);
M(elemNodes(e,1),elemNodes(e,2))=M(elemNodes(e,1),elemNodes(e,2))+Me(1,2);
M(elemNodes(e,2),elemNodes(e,1))=M(elemNodes(e,2),elemNodes(e,1))+Me(2,1);
M(elemNodes(e,2),elemNodes(e,2))=M(elemNodes(e,2),elemNodes(e,2))+Me(2,2);
end
%Apply Boundary Conditions (Reduce Matrices)
T1=1;
RHS=M*Tnew;
for i=1:numNodes-1;
for j=1:numNodes-1;
Kred(i,j)=K(i+1,j+1);
Mred(i,j)=M(i+1,j+1);
end
Subr(i)=(K(i+1,1)+M(i+1,1))*T1;
RHSr(i)=RHS(i+1);
end
%Solve
StiffI=(Mred+Kred)^-1;
Tnewr=StiffI*(RHSr'-Subr');
for i=1:numNodes-1;
Tnew(i+1)=Tnewr(i);
end
Tnew(1)=1.;
Tnew
end

View file

@ -0,0 +1,98 @@
function [] = FESolveSimp()
% MATLAB based 1-D XFEM Solver
% J. Grogan (2012)
clear all
% Define Geometry
len=10.;
% Define Section Properties
rho=1.;
% Generate Mesh
numElem=10;
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=1;
% Initial temperatures
Tnew=zeros(numNodes,1);
Bound=zeros(numNodes,1);
Tnew(1)=1.;
Bound(1)=1.;
% 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(2*ndof);
Me=zeros(2*ndof);
crdn1=ndCoords(elemNodes(e,1));
crdn2=ndCoords(elemNodes(e,2));
elen=abs(crdn2-crdn1);
ajacob=elen/2.;
gpx(1)=-1/sqrt(3.);
gpx(2)=1/sqrt(3.);
w(1)=1.;
w(2)=1.;
% Loop Through Int Points
for i=1:2;
c=gpx(i);
phi(1)=(1.-c)/2.;
phi(2)=(1.+c)/2.;
cond=1.;
spec=1.;
phic(1)=-0.5;
phic(2)=0.5;
phix(1)=phic(1)/ajacob;
phix(2)=phic(2)/ajacob;
we=ajacob*w(i);
Ke=Ke+we*cond*phix'*phix;
Me=Me+(we*rho*spec*phi'*phi)/dtime;
end
% Assemble Global Matrices
gnum=elemNodes(e,1);
for i=1:2;
for j=1:2;
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
end
end
%Remove NON-ENHANCED DOFs(Reduce Matrices)
iindex=0.;
A=K+M;
Sub=A*Bound;
RHS=M*Tnew-Sub;
% Apply Boundary Conditions
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';
% Restore Matrices
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,221 @@
function [] = FESolveX()
% MATLAB based 1-D XFEM Solver
% J. Grogan (2012)
clear all
% Define Geometry
len=10.;
% Define Section Properties
rho=1.;
% Generate Mesh
numElem=40;
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=4.6;
% Initial temperatures
Tnew=zeros(numNodes*2,1);
%storage
stored(1)=dpos;
for e=1:numElem
crdn1=ndCoords(elemNodes(e,1));
if crdn1<=dpos
Tnew(2*elemNodes(e,1)-1)=1.;
end
end
% Define Time Step
dtime=0.1;
tsteps=10;
time=0.;
% penalty term
beta=200.;
% 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=1.*(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.);
fdofs(1)=2*elemNodes(e,1);
fdofs(2)=2*elemNodes(e,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.;
spec=0.01;
else
cond=1.;
spec=1.;
end
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
% 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)));
tpos=gm(1)*Tnew(1)+gm(2)*Tnew(2)+gm(3)*Tnew(3)+gm(4)*Tnew(4);
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 inactive DOFs(Reduce Matrices)
T1=1;
RHS=M*Tnew;
iindex=0;
for i=1:ndof*numNodes;
check=1;
if i==fdofs(1)|i==fdofs(2)
check=0;
elseif mod(i,2)~=0 & i~=1
check=0;
end
if check==0
jindex=0;
iindex=iindex+1;
for j=1:ndof*numNodes;
check=1;
if j==fdofs(1)|j==fdofs(2)
check=0;
elseif mod(j,2)~=0 & j~=1
check=0;
end
if check==0
jindex=jindex+1;
Kred(iindex,jindex)=K(i,j);
Mred(iindex,jindex)=M(i,j);
end
end
Subr(iindex)=(K(i,1)+M(i,1))*T1;
RHSr(iindex)=RHS(i);
pforcer(iindex)=pforce(i);
end
end
%Solve
StiffI=(Mred+Kred)^-1;
Tnewr=StiffI*(RHSr'-Subr'+pforcer');
iindex=0.;
for i=1:ndof*numNodes;
check=1;
if i==fdofs(1)|i==fdofs(2)
check=0;
elseif mod(i,2)~=0 & i~=1
check=0;
end
if check==0
iindex=iindex+1;
Tnew(i)=Tnewr(iindex);
else
Tnew(i)=0.;
end
end
Tnew(1)=1.;
Tnew
end
stored'

View file

@ -0,0 +1,269 @@
function [] = FESolveX2D()
% MATLAB based 2-D XFEM Solver
% J. Grogan (2012)
clear all
% Define Mesh
NumX=4;
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=10;
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,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,199 @@
function [] = FESolveXT()
% MATLAB based 1-D XFEM Solver
% J. Grogan (2012)
clear all
% Define Geometry
len=10.;
% Define Section Properties
rho=1.;
% Generate Mesh
numElem=10;
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=4.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.;
Bound(2*elemNodes(e,n)-1)=1.;
end
end
end
% Define Time Step
dtime=0.01;
tsteps=10;
time=0.;
% penalty term
beta=50.;
% 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=1.*(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);
if term<0
cond=0.;
spec=0.01;
else
cond=1.;
spec=1.;
end
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
% 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)));
tpos=gm(1)*Tnew(1)+gm(2)*Tnew(2)+gm(3)*Tnew(3)+gm(4)*Tnew(4);
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 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
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,269 @@
function [] = FESolveXT2()
% MATLAB based 1-D XFEM Solver
% J. Grogan (2012)
clear all
% Define Geometry
len=1.;
% Define Section Properties
rho=1.;
% Generate Mesh
numElem=16;
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.4;
% 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.001;
tsteps=100;
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));
% 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
Ke;
Me;
% 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,128 @@
function [] = GetF()
% set up grid
gd=0.;
numElem=4;
eLen=0.25;
for i=1:numElem+1
ndCrd(i)=gd;
gd=gd+eLen;
end
for i=1:numElem
elemNod(i,1)=i;
elemNod(i,2)=i+1;
end
% Initial level set
dpos=0.1;
for i=1:numElem+1
lSet(i)=sign(ndCrd(i)-dpos)*abs(dpos-ndCrd(i));
end
lSet'
for tstep=1:120
% Velocity BC
F=zeros(numElem+1,1);
for i=1:numElem
if sign(lSet(elemNod(i,1)))~=sign(lSet(elemNod(i,2)))
F(elemNod(i,1))= 0.0005;
F(elemNod(i,2))= 0.0005;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numElem+1);
for i=1:numElem
pos(1)=-1/sqrt(3);
pos(2)=1/sqrt(3);
AfL=zeros(2);
AfLGLS=zeros(2);
for j=1:2
shp(1)=(1-pos(j))/2.;
shp(2)=(1+pos(j))/2.;
dshp(1)=-0.5;
dshp(2)=0.5;
rset=shp(1)*lSet(elemNod(i,1))+shp(2)*lSet(elemNod(i,2));
dls=dshp(1)*lSet(elemNod(i,1))+dshp(2)*lSet(elemNod(i,2));
AfL=AfL+shp'*sign(rset)*(dls*dshp);
AfLGLS=AfLGLS+(dshp'*dls)*(0.25/abs(dls))*(dls*dshp);
end
for k=1:2;
for j=1:2;
A(elemNod(i,j),elemNod(i,k))=A(elemNod(i,j),elemNod(i,k))+AfL(j,k)+AfLGLS(j,k);
end
end
end
% Apply BCs
RHS=zeros(numElem+1,1);
Sub=A*F;
iindex=0;
for i=1:numElem+1
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numElem+1
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:numElem+1
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numElem+1);
mMatGLS=zeros(numElem+1);
f1=zeros(numElem+1,1);
f2=zeros(numElem+1,1);
f3=zeros(numElem+1,1);
h=0.25;
visc=0.000;
for i=1:numElem
pos(1)=-1/sqrt(3);
pos(2)=1/sqrt(3);
mMatL=zeros(2);
mMatGLSL=zeros(2);
f1L=zeros(2,1);
f2L=zeros(2,1);
f3L=zeros(2,1);
for j=1:2
shp(1)=(1-pos(j))/2.;
shp(2)=(1+pos(j))/2.;
dshp(1)=-0.5;
dshp(2)=0.5;
Floc=shp(1)*F(elemNod(i,1))+shp(2)*F(elemNod(i,2));
rset=shp(1)*lSet(elemNod(i,1))+shp(2)*lSet(elemNod(i,2));
dls=dshp(1)*lSet(elemNod(i,1))+dshp(2)*lSet(elemNod(i,2));
mMatL=mMatL+shp'*shp;
mMatGLSL=mMatGLSL+((dshp'*(dls/abs(dls)))*Floc*(h/abs(Floc)))*shp;
f1L=f1L+shp'*Floc*abs(dls);
f2L=f2L+(dshp'*(dls/abs(dls))*Floc)*(h/abs(Floc))*Floc*abs(dls);
vs=h*((abs(visc+Floc*abs(dls)))/(abs(Floc*dls)+h));
f3L=f3L+vs*dshp'*dls;
end
for k=1:2;
for j=1:2;
mMat(elemNod(i,j),elemNod(i,k))=mMat(elemNod(i,j),elemNod(i,k))+mMatL(j,k);
mMatGLS(elemNod(i,j),elemNod(i,k))=mMatGLS(elemNod(i,j),elemNod(i,k))+mMatGLSL(j,k);
end
f1(elemNod(i,k))=f1(elemNod(i,k))+f1L(k);
f2(elemNod(i,k))=f2(elemNod(i,k))+f2L(k);
f3(elemNod(i,k))=f3(elemNod(i,k))+f3L(k);
end
end
dt=0.01;
lSet=lSet-((((mMat+mMatGLS)^-1)/dt)*(f1+f2+f3))';
lSet'
end

View file

@ -0,0 +1,146 @@
function [] = S2D()
% MATLAB based 2-D XFEM Solver
% J. Grogan (2012)
clear all
% Define Mesh
NumX=10;
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);
% Define Section Properties
rho=1.;
cond=1.;
spec=1.;
% initial interface position
dpos=0.25;
% 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<=dpos
Tnew(Element(e,n))=1.;
Bound(Element(e,n))=1.;
end
end
end
% Define Time Step
dtime=0.1;
tsteps=10;
% 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
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;
% 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);
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=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)
RHS=M*Tnew;
A=K+M;
Sub=A*Bound;
iindex=0;
for i=1:numNodes;
if Bound(i)==0.;
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
jindex=0;
for j=1:numNodes;
if Bound(j)==0.;
jindex=jindex+1;
Ared(iindex,jindex)=A(i,j);
end
end
end
end
%Solve
Tnewr=(Ared^-1)*RHSred';
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,270 @@
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
Ke;
Me;
% 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,197 @@
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
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);
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
% 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;
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,234 @@
function [] = 2DLevelSet()
clear all
% Define Main Solution Mesh
NumX=8;
NumY=8;
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);
% 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:1.:8);
Z=zeros(9);
for i=1:81
Z(i)=lSet(i);
end
surf(X,Y,Z)
% LS Algorithm Parameters
lSet'
bandwidth=10.;
% Loop through timesteps
for tstep=1:100
% Identify Narrow Band Elements
NBindex=0;
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
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,2);
NBelem(NBindex,3)=Element(i,3);
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,3);
NBelem(NBindex,3)=Element(i,4);
end
end
% Velocity BC
F=zeros(numNodes,1);
for i=1:NBindex
if sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,2)))||sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,3)))
F(NBelem(i,1))= 1.;
F(NBelem(i,2))= 1.;
F(NBelem(i,3))= 1.;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numNodes);
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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(numNodes,1);
Sub=A*F;
iindex=0;
for i=1:numNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numNodes
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:numNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numNodes);
mMatGLS=zeros(numNodes);
f1=zeros(numNodes,1);
f2=zeros(numNodes,1);
f3=zeros(numNodes,1);
h2=0.00001;
visc=0.0005;
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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;
lSet=lSet-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))';
end
lSet'
%[X Y]=meshgrid(0:1.:8);
%Z=zeros(9);
%for i=1:81
% Z(i)=lSet(i);
%end
%surf(X,Y,Z)

View file

@ -0,0 +1,234 @@
function [] = 2DLevelSetFMM()
clear all
% Define Main Solution 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);
% 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:1.:8);
%Z=zeros(9);
%for i=1:81
% Z(i)=lSet(i);
%end
%surf(X,Y,Z)
% LS Algorithm Parameters
lSet'
bandwidth=10.;
% Loop through timesteps
for tstep=1:1
% Identify Narrow Band Elements
NBindex=0;
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
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,2);
NBelem(NBindex,3)=Element(i,3);
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,3);
NBelem(NBindex,3)=Element(i,4);
end
end
% Velocity BC
F=zeros(numNodes,1);
for i=1:NBindex
if sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,2)))||sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,3)))
F(NBelem(i,1))= 1.;
F(NBelem(i,2))= 1.;
F(NBelem(i,3))= 1.;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numNodes);
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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(numNodes,1);
Sub=A*F;
iindex=0;
for i=1:numNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numNodes
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:numNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numNodes);
mMatGLS=zeros(numNodes);
f1=zeros(numNodes,1);
f2=zeros(numNodes,1);
f3=zeros(numNodes,1);
h2=0.00001;
visc=0.0005;
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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;
lSet=lSet-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))';
end
lSet'
%[X Y]=meshgrid(0:1.:8);
%Z=zeros(9);
%for i=1:81
% Z(i)=lSet(i);
%end
%surf(X,Y,Z)

View file

@ -0,0 +1,322 @@
function [] = F2DLevelSetFMM()
clear all
% Define Main Solution Mesh
NumX=5;
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);
% 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:1.:8);
%Z=zeros(9);
%for i=1:81
% Z(i)=lSet(i);
%end
%surf(X,Y,Z)
% LS Algorithm Parameters
lSet'
bandwidth=3.;
% Loop through timesteps
for tstep=1:1
% 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 NewNums(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:NBindex
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(lSet(NBelem(i,j)))<=lmin
check=1;
tempindex=j;
end
end
ltot=ltot+abs(lSet(NBelem(i,j)));
end
if check==1 & ltot/3.<=avlmin
eindex=i;
nindex=tempindex;
lmin=lSet(NBelem(eindex,nindex));
avlmin=ltot/3.;
end
end
end
if maincheck==0
% Find New LS for point
xp=Node(NBelem(eindex,nindex),1);
yp=Node(NBelem(eindex,nindex),2);
count=0;
for i=1:3
if i~=nindex
count=count+1;
x(count)=Node(NBelem(eindex,i),1);
y(count)=Node(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
% lSet=newlSet;
end
lSet'

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,221 @@
function [] = FESolveX()
% MATLAB based XFEM Solver
% J. Grogan (2012)
clear all
% Define Geometry
len=10.;
% Define Section Properties
rho=1.;
% Generate Mesh
numElem=10;
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=5.;
% Initial temperatures
Tnew=zeros(numNodes*2,1);
%storage
stored(1)=dpos;
for e=1:numElem
crdn1=ndCoords(elemNodes(e,1));
if crdn1<=dpos
Tnew(2*elemNodes(e,1)-1)=1.;
end
end
% Define Time Step
dtime=0.05;
tsteps=20;
time=0.;
% penalty term
beta=40.;
% 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/charlen)*(2*t(1)+t(2)-t(3)-2*t(4));
% 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.);
fdofs(1)=2*elemNodes(e,1);
fdofs(2)=2*elemNodes(e,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.;
spec=0.01;
else
cond=1.;
spec=1.;
end
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
% 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)));
tpos=gm(1)*Tnew(1)+gm(2)*Tnew(2)+gm(3)*Tnew(3)+gm(4)*Tnew(4);
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 inactive DOFs(Reduce Matrices)
T1=1;
RHS=M*Tnew;
iindex=0;
for i=1:ndof*numNodes;
check=1;
if i==fdofs(1)|i==fdofs(2)
check=0;
elseif mod(i,2)~=0 & i~=1
check=0;
end
if check==0
jindex=0;
iindex=iindex+1;
for j=1:ndof*numNodes;
check=1;
if j==fdofs(1)|j==fdofs(2)
check=0;
elseif mod(j,2)~=0 & j~=1
check=0;
end
if check==0
jindex=jindex+1;
Kred(iindex,jindex)=K(i,j);
Mred(iindex,jindex)=M(i,j);
end
end
Subr(iindex)=(K(i,1)+M(i,1))*T1;
RHSr(iindex)=RHS(i);
pforcer(iindex)=pforce(i);
end
end
%Solve
Mred+Kred;
StiffI=(Mred+Kred)^-1;
Tnewr=StiffI*(RHSr'-Subr'+pforcer');
iindex=0.;
for i=1:ndof*numNodes;
check=1;
if i==fdofs(1)|i==fdofs(2)
check=0;
elseif mod(i,2)~=0 & i~=1
check=0;
end
if check==0
iindex=iindex+1;
Tnew(i)=Tnewr(iindex);
else
Tnew(i)=0.;
end
end
Tnew(1)=1.;
Tnew
end
stored'

View file

@ -0,0 +1,128 @@
function [] = GetF()
% set up grid
gd=0.;
numElem=4;
eLen=0.25;
for i=1:numElem+1
ndCrd(i)=gd;
gd=gd+eLen;
end
for i=1:numElem
elemNod(i,1)=i;
elemNod(i,2)=i+1;
end
% Initial level set
dpos=0.1;
for i=1:numElem+1
lSet(i)=sign(ndCrd(i)-dpos)*abs(dpos-ndCrd(i));
end
lSet'
for tstep=1:1
% Velocity BC
F=zeros(numElem+1,1);
for i=1:numElem
if sign(lSet(elemNod(i,1)))~=sign(lSet(elemNod(i,2)))
F(elemNod(i,1))= 0.0005;
F(elemNod(i,2))= 0.0005;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numElem+1);
for i=1:numElem
pos(1)=-1/sqrt(3);
pos(2)=1/sqrt(3);
AfL=zeros(2);
AfLGLS=zeros(2);
for j=1:2
shp(1)=(1-pos(j))/2.;
shp(2)=(1+pos(j))/2.;
dshp(1)=-0.5;
dshp(2)=0.5;
rset=shp(1)*lSet(elemNod(i,1))+shp(2)*lSet(elemNod(i,2));
dls=dshp(1)*lSet(elemNod(i,1))+dshp(2)*lSet(elemNod(i,2));
AfL=AfL+shp'*sign(rset)*(dls*dshp);
AfLGLS=AfLGLS+(dshp'*dls)*(0.25/abs(dls))*(dls*dshp);
end
for k=1:2;
for j=1:2;
A(elemNod(i,j),elemNod(i,k))=A(elemNod(i,j),elemNod(i,k))+AfL(j,k)+AfLGLS(j,k)
end
end
end
% Apply BCs
RHS=zeros(numElem+1,1);
Sub=A*F;
iindex=0;
for i=1:numElem+1
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numElem+1
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:numElem+1
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numElem+1);
mMatGLS=zeros(numElem+1);
f1=zeros(numElem+1,1);
f2=zeros(numElem+1,1);
f3=zeros(numElem+1,1);
h=0.25;
visc=0.000;
for i=1:numElem
pos(1)=-1/sqrt(3);
pos(2)=1/sqrt(3);
mMatL=zeros(2);
mMatGLSL=zeros(2);
f1L=zeros(2,1);
f2L=zeros(2,1);
f3L=zeros(2,1);
for j=1:2
shp(1)=(1-pos(j))/2.;
shp(2)=(1+pos(j))/2.;
dshp(1)=-0.5;
dshp(2)=0.5;
Floc=shp(1)*F(elemNod(i,1))+shp(2)*F(elemNod(i,2));
rset=shp(1)*lSet(elemNod(i,1))+shp(2)*lSet(elemNod(i,2));
dls=dshp(1)*lSet(elemNod(i,1))+dshp(2)*lSet(elemNod(i,2));
mMatL=mMatL+shp'*shp;
mMatGLSL=mMatGLSL+((dshp'*(dls/abs(dls)))*Floc*(h/abs(Floc)))*shp;
f1L=f1L+shp'*Floc*abs(dls);
f2L=f2L+(dshp'*(dls/abs(dls))*Floc)*(h/abs(Floc))*Floc*abs(dls);
vs=h*((abs(visc+Floc*abs(dls)))/(abs(Floc*dls)+h));
f3L=f3L+vs*dshp'*dls;
end
for k=1:2;
for j=1:2;
mMat(elemNod(i,j),elemNod(i,k))=mMat(elemNod(i,j),elemNod(i,k))+mMatL(j,k);
mMatGLS(elemNod(i,j),elemNod(i,k))=mMatGLS(elemNod(i,j),elemNod(i,k))+mMatGLSL(j,k);
end
f1(elemNod(i,k))=f1(elemNod(i,k))+f1L(k);
f2(elemNod(i,k))=f2(elemNod(i,k))+f2L(k);
f3(elemNod(i,k))=f3(elemNod(i,k))+f3L(k);
end
end
dt=0.01;
lSet=lSet-((((mMat+mMatGLS)^-1)/dt)*(f1+f2+f3))';
lSet';
end

View file

@ -0,0 +1,200 @@
function [] = GetF2D_()
clear all
% Define Main Solution Mesh
NumX=10;
NumY=10;
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);
% Define Initial Level Set
centx=5.;
centy=5.;
rad=2.5;
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
% Plot initial level set
[X,Y]=meshgrid(0:1.:10);
Z=zeros(11);
for i=1:numNodes
Z(i)=lSet(i);
end
surf(X,Y,Z)
% LS Algorithm Parameters
bandwith=10.;
% Loop through timesteps
for tstep=1:1
% Identify Narrow Band Elements
NBindex=0;
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
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,2);
NBelem(NBindex,3)=Element(i,3);
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,3);
NBelem(NBindex,3)=Element(i,4);
end
end
% Velocity BC
F=zeros(numNodes,1);
for i=1:NBindex
if lSet(NBelem(i,1))~=lSet(NBelem(i,2)) || lSet(NBelem(i,1))~=lSet(NBelem(i,3))
F(NBelem(i,1))= 0.0005;
F(NBelem(i,2))= 0.0005;
F(NBelem(i,3))= 0.0005;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numNodes);
for i=1:NBindex
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;
AfL=zeros(4);
AfLGLS=zeros(4);
for j=1:4
g=gx(j);
h=hx(j);
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);
phig(1)=0.25*-(1.-h);
phig(2)=0.25*(1.-h);
phig(3)=0.25*(1.+h);
phig(4)=0.25*-(1.+h);
rset=phi(1)*lSet(Element(i,1))+phi(2)*lSet(Element(i,2))+phi(3)*lSet(Element(i,3))+phi(4)*lSet(Element(i,4));
dls=phig(1)*lSet(Element(i,1))+phig(2)*lSet(Element(i,2))+phig(3)*lSet(Element(i,3))+phig(4)*lSet(Element(i,4));
AfL=AfL+(phi'*sign(rset))*(dls*phig);
AfLGLS=AfLGLS+(phig'*dls)*(1./abs(dls))*(dls*phig);
end
for k=1:4;
for j=1:4;
A(Element(i,j),Element(i,k))=A(Element(i,j),Element(i,k))+AfL(j,k)+AfLGLS(j,k);
end
end
end
% Apply BCs
RHS=zeros(numNodes,1);
Sub=A*F;
iindex=0;
for i=1:numNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numNodes
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:numNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numNodes);
mMatGLS=zeros(numNodes);
f1=zeros(numNodes,1);
f2=zeros(numNodes,1);
f3=zeros(numNodes,1);
h=1.;
visc=0.000;
for i=1:numElem
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;
mMatL=zeros(4);
mMatGLSL=zeros(4);
f1L=zeros(4,1);
f2L=zeros(4,1);
f3L=zeros(4,1);
for j=1:4
g=gx(j);
h=hx(j);
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);
phig(1)=0.25*-(1.-h);
phig(2)=0.25*(1.-h);
phig(3)=0.25*(1.+h);
phig(4)=0.25*-(1.+h);
Floc=phi(1)*F(Element(i,1))+phi(2)*F(Element(i,2))+phi(3)*F(Element(i,3))+phi(4)*F(Element(i,4));
rset=phi(1)*lSet(Element(i,1))+phi(2)*lSet(Element(i,2))+phi(3)*lSet(Element(i,3))+phi(4)*lSet(Element(i,4));
dls=phig(1)*lSet(Element(i,1))+phig(2)*lSet(Element(i,2))+phig(3)*lSet(Element(i,3))+phig(4)*lSet(Element(i,4));
mMatL=mMatL+phi'*phi;
mMatGLSL=mMatGLSL+((phig'*(dls/abs(dls)))*Floc*(h/abs(Floc)))*phi;
f1L=f1L+phi'*Floc*abs(dls);
f2L=f2L+(phig'*(dls/abs(dls))*Floc)*(h/abs(Floc))*Floc*abs(dls);
vs=h*((abs(visc+Floc*abs(dls)))/(abs(Floc*dls)+h));
f3L=f3L+vs*phig'*dls;
end
for k=1:4;
for j=1:4;
mMat(Element(i,j),Element(i,k))=mMat(Element(i,j),Element(i,k))+mMatL(j,k);
mMatGLS(Element(i,j),Element(i,k))=mMatGLS(Element(i,j),Element(i,k))+mMatGLSL(j,k);
end
f1(Element(i,k))=f1(Element(i,k))+f1L(k);
f2(Element(i,k))=f2(Element(i,k))+f2L(k);
f3(Element(i,k))=f3(Element(i,k))+f3L(k);
end
end
dt=0.01;
lSet=lSet-((((mMat+mMatGLS)^-1)/dt)*(f1+f2+f3))';
end
%scatter3(Node(:,1), Node(:,2), lSet');

View file

@ -0,0 +1,200 @@
function [] = GetF2D()
clear all
% Define Main Solution Mesh
NumX=10;
NumY=10;
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);
% Define Initial Level Set
centx=5.;
centy=5.;
rad=2.5;
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
% Plot initial level set
[X,Y]=meshgrid(0:1.:10);
Z=zeros(11);
for i=1:numNodes
Z(i)=lSet(i);
end
surf(X,Y,Z)
% LS Algorithm Parameters
bandwith=10.;
% Loop through timesteps
for tstep=1:1
% Identify Narrow Band Elements
NBindex=0;
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
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,2);
NBelem(NBindex,3)=Element(i,3);
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,3);
NBelem(NBindex,3)=Element(i,4);
end
end
% Velocity BC
F=zeros(numNodes,1);
for i=1:NBindex
if lSet(NBelem(i,1))~=lSet(NBelem(i,2)) || lSet(NBelem(i,1))~=lSet(NBelem(i,3))
F(NBelem(i,1))= 0.0005;
F(NBelem(i,2))= 0.0005;
F(NBelem(i,3))= 0.0005;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numNodes);
for i=1:NBindex
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;
AfL=zeros(4);
AfLGLS=zeros(4);
for j=1:4
g=gx(j);
h=hx(j);
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);
phig(1)=0.25*-(1.-h);
phig(2)=0.25*(1.-h);
phig(3)=0.25*(1.+h);
phig(4)=0.25*-(1.+h);
rset=phi(1)*lSet(Element(i,1))+phi(2)*lSet(Element(i,2))+phi(3)*lSet(Element(i,3))+phi(4)*lSet(Element(i,4));
dls=phig(1)*lSet(Element(i,1))+phig(2)*lSet(Element(i,2))+phig(3)*lSet(Element(i,3))+phig(4)*lSet(Element(i,4));
AfL=AfL+(phi'*sign(rset))*(dls*phig);
AfLGLS=AfLGLS+(phig'*dls)*(1./abs(dls))*(dls*phig);
end
for k=1:4;
for j=1:4;
A(Element(i,j),Element(i,k))=A(Element(i,j),Element(i,k))+AfL(j,k)+AfLGLS(j,k)
end
end
end
% Apply BCs
RHS=zeros(numNodes,1);
Sub=A*F;
iindex=0;
for i=1:numNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numNodes
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:numNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numNodes);
mMatGLS=zeros(numNodes);
f1=zeros(numNodes,1);
f2=zeros(numNodes,1);
f3=zeros(numNodes,1);
h=1.;
visc=0.000;
for i=1:numElem
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;
mMatL=zeros(4);
mMatGLSL=zeros(4);
f1L=zeros(4,1);
f2L=zeros(4,1);
f3L=zeros(4,1);
for j=1:4
g=gx(j);
h=hx(j);
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);
phig(1)=0.25*-(1.-h);
phig(2)=0.25*(1.-h);
phig(3)=0.25*(1.+h);
phig(4)=0.25*-(1.+h);
Floc=phi(1)*F(Element(i,1))+phi(2)*F(Element(i,2))+phi(3)*F(Element(i,3))+phi(4)*F(Element(i,4));
rset=phi(1)*lSet(Element(i,1))+phi(2)*lSet(Element(i,2))+phi(3)*lSet(Element(i,3))+phi(4)*lSet(Element(i,4));
dls=phig(1)*lSet(Element(i,1))+phig(2)*lSet(Element(i,2))+phig(3)*lSet(Element(i,3))+phig(4)*lSet(Element(i,4));
mMatL=mMatL+phi'*phi;
mMatGLSL=mMatGLSL+((phig'*(dls/abs(dls)))*Floc*(h/abs(Floc)))*phi;
f1L=f1L+phi'*Floc*abs(dls);
f2L=f2L+(phig'*(dls/abs(dls))*Floc)*(h/abs(Floc))*Floc*abs(dls);
vs=h*((abs(visc+Floc*abs(dls)))/(abs(Floc*dls)+h));
f3L=f3L+vs*phig'*dls;
end
for k=1:4;
for j=1:4;
mMat(Element(i,j),Element(i,k))=mMat(Element(i,j),Element(i,k))+mMatL(j,k);
mMatGLS(Element(i,j),Element(i,k))=mMatGLS(Element(i,j),Element(i,k))+mMatGLSL(j,k);
end
f1(Element(i,k))=f1(Element(i,k))+f1L(k);
f2(Element(i,k))=f2(Element(i,k))+f2L(k);
f3(Element(i,k))=f3(Element(i,k))+f3L(k);
end
end
dt=0.01;
lSet=lSet-((((mMat+mMatGLS)^-1)/dt)*(f1+f2+f3))';
end
%scatter3(Node(:,1), Node(:,2), lSet');

View file

@ -0,0 +1,232 @@
function [] = GetF2D_T()
clear all
% Define Main Solution Mesh
NumX=2;
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);
% Define Initial Level Set
%centx=5.;
%centy=5.;
%rad=2.5;
%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]=meshgrid(0:1.:10);
%Z=zeros(11);
%for i=1:numNodes
% Z(i)=lSet(i);
%end
%surf(X,Z)
% LS Algorithm Parameters
bandwidth=10.;
% Loop through timesteps
for tstep=1:1
% Identify Narrow Band Elements
NBindex=0;
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
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,2);
NBelem(NBindex,3)=Element(i,3);
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,3);
NBelem(NBindex,3)=Element(i,4);
end
end
% Velocity BC
F=zeros(numNodes,1);
for i=1:NBindex
if sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,2)))||sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,3)))
F(NBelem(i,1))= 0.05;
F(NBelem(i,2))= 0.05;
F(NBelem(i,3))= 0.05;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numNodes);
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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(numNodes,1);
Sub=A*F;
iindex=0;
for i=1:numNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numNodes
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:numNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numNodes);
mMatGLS=zeros(numNodes);
f1=zeros(numNodes,1);
f2=zeros(numNodes,1);
f3=zeros(numNodes,1);
h=1.;
visc=0.001;
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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*(h/abs(Floc)))*phi/3.;
f1L=f1L+phi'*Floc*norm(delset)/3.;
f2L=f2L+(delphi'*(delset/norm(delset))*Floc)*(h/abs(Floc))*Floc*norm(delset)/3.;
vs=h*((abs(visc+Floc*norm(delset)))/(norm(Floc*delset)+h));
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
(mMat+mMatGLS)^-1
f1+f2+f3
dt=0.0001;
-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))'
lSet=lSet-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))';
end
lSet';
%scatter3(Node(:,1), Node(:,2), lSet');

View file

@ -0,0 +1,233 @@
function [] = GetF2D_T()
clear all
% Define Main Solution Mesh
NumX=2;
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);
% Define Initial Level Set
%centx=5.;
%centy=5.;
%rad=2.5;
%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.5;
lSet(i)=dist;
end
% Plot initial level set
%[X]=meshgrid(0:1.:10);
%Z=zeros(11);
%for i=1:numNodes
% Z(i)=lSet(i);
%end
%surf(X,Z)
% LS Algorithm Parameters
bandwidth=10.;
% Loop through timesteps
for tstep=1:1
% Identify Narrow Band Elements
NBindex=0;
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
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,2);
NBelem(NBindex,3)=Element(i,3);
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,3);
NBelem(NBindex,3)=Element(i,4);
end
end
% Velocity BC
F=zeros(numNodes,1);
for i=1:NBindex
if sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,2)))||sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,3)))
F(NBelem(i,1))= 0.05;
F(NBelem(i,2))= 0.05;
F(NBelem(i,3))= 0.05;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numNodes);
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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(numNodes,1);
Sub=A*F;
iindex=0;
for i=1:numNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numNodes
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:numNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numNodes);
mMatGLS=zeros(numNodes);
f1=zeros(numNodes,1);
f2=zeros(numNodes,1);
f3=zeros(numNodes,1);
h=1.;
visc=0.0005;
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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*(h/abs(Floc)))*phi/3.;
f1L=f1L+phi'*Floc*norm(delset)/3.;
f2L=f2L+(delphi'*(delset/norm(delset))*Floc)*(h/abs(Floc))*Floc*norm(delset)/3.;
vs=h*((abs(visc+Floc*norm(delset)))/(norm(Floc*delset)+h));
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
mMat
mMatGLS
(mMat+mMatGLS)^-1
f1+f2+f3
dt=0.1;
-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))'
lSet=lSet-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))';
end
lSet';
%scatter3(Node(:,1), Node(:,2), lSet');

View file

@ -0,0 +1,234 @@
function [] = GetF2D_Z()
clear all
% Define Main Solution Mesh
NumX=8;
NumY=8;
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);
% 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:1.:8);
Z=zeros(9);
for i=1:81
Z(i)=lSet(i);
end
surf(X,Y,Z)
% LS Algorithm Parameters
lSet'
bandwidth=10.;
% Loop through timesteps
for tstep=1:100
% Identify Narrow Band Elements
NBindex=0;
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
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,2);
NBelem(NBindex,3)=Element(i,3);
NBindex=NBindex+1;
NBelem(NBindex,1)=Element(i,1);
NBelem(NBindex,2)=Element(i,3);
NBelem(NBindex,3)=Element(i,4);
end
end
% Velocity BC
F=zeros(numNodes,1);
for i=1:NBindex
if sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,2)))||sign(lSet(NBelem(i,1)))~=sign(lSet(NBelem(i,3)))
F(NBelem(i,1))= 1.;
F(NBelem(i,2))= 1.;
F(NBelem(i,3))= 1.;
end
end
% Assemble 'Stiffness' Matrices
A=zeros(numNodes);
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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(numNodes,1);
Sub=A*F;
iindex=0;
for i=1:numNodes
if F(i)==0.
iindex=iindex+1;
RHSred(iindex)=RHS(i)-Sub(i);
Fred=0.;
jindex=0;
for j=1:numNodes
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:numNodes
if F(i)==0.
iindex=iindex+1;
F(i)=Fred(iindex);
end
end
% Update level set
mMat=zeros(numNodes);
mMatGLS=zeros(numNodes);
f1=zeros(numNodes,1);
f2=zeros(numNodes,1);
f3=zeros(numNodes,1);
h2=0.00001;
visc=0.0005;
for i=1:NBindex
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(NBelem(i,1),1);
y1=Node(NBelem(i,1),2);
x2=Node(NBelem(i,2),1);
y2=Node(NBelem(i,2),2);
x3=Node(NBelem(i,3),1);
y3=Node(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=[lSet(NBelem(i,1));lSet(NBelem(i,2));lSet(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;
lSet=lSet-((((mMat+mMatGLS)^-1)*dt)*(f1+f2+f3))';
end
lSet'
%[X Y]=meshgrid(0:1.:8);
%Z=zeros(9);
%for i=1:81
% Z(i)=lSet(i);
%end
%surf(X,Y,Z)

View file

@ -0,0 +1,2 @@
function [] = testGrid()

View file

@ -0,0 +1,4 @@
function [] = testGrid()
[X,Y]=meshgrid(1:1:10);
Z=2*X+Y
surf(X,Y,Z)

Some files were not shown because too many files have changed in this diff Show more