phd-scripts/Unpublished/3D_Voxel_Assign/GeomGenPost.f90

190 lines
5.6 KiB
Fortran
Raw Normal View History

2024-05-13 19:50:21 +00:00
!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