|
|
@ -33,7 +33,8 @@ module elements
|
|
|
|
integer :: atom_types = 0
|
|
|
|
integer :: atom_types = 0
|
|
|
|
|
|
|
|
|
|
|
|
!Variables for creating elements based on primitive cells
|
|
|
|
!Variables for creating elements based on primitive cells
|
|
|
|
real(kind=dp) :: cubic_cell(3,8), fcc_cell(3,8), fcc_mat(3,3), fcc_inv(3,3), bcc_cell(3,8), bcc_mat(3,3), bcc_inv(3,3)
|
|
|
|
real(kind=dp) :: cubic_cell(3,8), fcc_cell(3,8), fcc_mat(3,3), fcc_inv(3,3), bcc_cell(3,8), bcc_mat(3,3), bcc_inv(3,3), &
|
|
|
|
|
|
|
|
cube20(3,20)
|
|
|
|
integer :: cubic_faces(4,6)
|
|
|
|
integer :: cubic_faces(4,6)
|
|
|
|
|
|
|
|
|
|
|
|
!Below are lattice type arrays which provide information on the general form of the elements.
|
|
|
|
!Below are lattice type arrays which provide information on the general form of the elements.
|
|
|
@ -72,6 +73,29 @@ module elements
|
|
|
|
0.0_dp, 1.0_dp, 1.0_dp /), &
|
|
|
|
0.0_dp, 1.0_dp, 1.0_dp /), &
|
|
|
|
shape(fcc_cell))
|
|
|
|
shape(fcc_cell))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!Now initialize the 20 node cube element
|
|
|
|
|
|
|
|
cube20 = reshape((/ 0.0_dp, 0.0_dp, 0.0_dp, &
|
|
|
|
|
|
|
|
1.0_dp, 0.0_dp, 0.0_dp, &
|
|
|
|
|
|
|
|
1.0_dp, 1.0_dp, 0.0_dp, &
|
|
|
|
|
|
|
|
0.0_dp, 1.0_dp, 0.0_dp, &
|
|
|
|
|
|
|
|
0.0_dp, 0.0_dp, 1.0_dp, &
|
|
|
|
|
|
|
|
1.0_dp, 0.0_dp, 1.0_dp, &
|
|
|
|
|
|
|
|
1.0_dp, 1.0_dp, 1.0_dp, &
|
|
|
|
|
|
|
|
0.0_dp, 1.0_dp, 1.0_dp, &
|
|
|
|
|
|
|
|
0.5_dp, 0.0_dp, 0.0_dp, &
|
|
|
|
|
|
|
|
1.0_dp, 0.5_dp, 0.0_dp, &
|
|
|
|
|
|
|
|
0.5_dp, 1.0_dp, 0.0_dp, &
|
|
|
|
|
|
|
|
0.0_dp, 0.5_dp, 0.0_dp, &
|
|
|
|
|
|
|
|
0.0_dp, 0.0_dp, 0.5_dp, &
|
|
|
|
|
|
|
|
1.0_dp, 0.0_dp, 0.5_dp, &
|
|
|
|
|
|
|
|
1.0_dp, 1.0_dp, 0.5_dp, &
|
|
|
|
|
|
|
|
0.0_dp, 1.0_dp, 0.5_dp, &
|
|
|
|
|
|
|
|
0.5_dp, 0.0_dp, 1.0_dp, &
|
|
|
|
|
|
|
|
1.0_dp, 0.5_dp, 1.0_dp, &
|
|
|
|
|
|
|
|
0.5_dp, 1.0_dp, 1.0_dp, &
|
|
|
|
|
|
|
|
0.0_dp, 0.5_dp, 1.0_dp /), &
|
|
|
|
|
|
|
|
shape(cube20))
|
|
|
|
|
|
|
|
|
|
|
|
!Now we create a list containing the list of vertices needed to describe the 6 cube faces
|
|
|
|
!Now we create a list containing the list of vertices needed to describe the 6 cube faces
|
|
|
|
cubic_faces(:,1) = (/ 1, 2, 3, 4 /)
|
|
|
|
cubic_faces(:,1) = (/ 1, 2, 3, 4 /)
|
|
|
|
cubic_faces(:,2) = (/ 1, 2, 6, 5 /)
|
|
|
|
cubic_faces(:,2) = (/ 1, 2, 6, 5 /)
|
|
|
@ -384,6 +408,8 @@ module elements
|
|
|
|
ng_node(i) = 8
|
|
|
|
ng_node(i) = 8
|
|
|
|
case('bcc')
|
|
|
|
case('bcc')
|
|
|
|
ng_node(i) = 8
|
|
|
|
ng_node(i) = 8
|
|
|
|
|
|
|
|
case('20fcc')
|
|
|
|
|
|
|
|
ng_node(i) = 20
|
|
|
|
end select
|
|
|
|
end select
|
|
|
|
|
|
|
|
|
|
|
|
if(ng_node(i) > max_ng_node) max_ng_node = ng_node(i)
|
|
|
|
if(ng_node(i) > max_ng_node) max_ng_node = ng_node(i)
|
|
|
@ -462,6 +488,34 @@ module elements
|
|
|
|
end do
|
|
|
|
end do
|
|
|
|
end do
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
case('20fcc')
|
|
|
|
|
|
|
|
!Now loop over all the possible sites
|
|
|
|
|
|
|
|
do it = 1, esize
|
|
|
|
|
|
|
|
t = (1.0_dp*(it-1)-(esize-1)/2)/(1.0_dp*(esize-1)/2)
|
|
|
|
|
|
|
|
do is =1, esize
|
|
|
|
|
|
|
|
s = (1.0_dp*(is-1)-(esize-1)/2)/(1.0_dp*(esize-1)/2)
|
|
|
|
|
|
|
|
do ir = 1, esize
|
|
|
|
|
|
|
|
r = (1.0_dp*(ir-1) - (esize-1)/2)/(1.0_dp*(esize-1)/2)
|
|
|
|
|
|
|
|
call quad_rhombshape(r,s,t,a_shape)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
do ibasis = 1, bnum
|
|
|
|
|
|
|
|
ia = ia + 1
|
|
|
|
|
|
|
|
do inod = 1, 20
|
|
|
|
|
|
|
|
type_interp(ia) = basis_type(ibasis,lat_type_temp)
|
|
|
|
|
|
|
|
r_interp(:,ia) = r_interp(:,ia) + a_shape(inod) * r_in(:,ibasis,inod)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(present(data_interp)) then
|
|
|
|
|
|
|
|
!If data is present then interpolate data arrays as well
|
|
|
|
|
|
|
|
data_interp(1,ia) = data_interp(1,ia) + eng(ibasis, inod)*a_shape(inod)
|
|
|
|
|
|
|
|
data_interp(2:4,ia) = data_interp(2:4,ia) + f(:, ibasis, inod)*a_shape(inod)
|
|
|
|
|
|
|
|
data_interp(5:10,ia) = data_interp(5:10,ia) + v(:, ibasis, inod)*a_shape(inod)
|
|
|
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
|
|
end do
|
|
|
|
end do
|
|
|
|
end do
|
|
|
|
end do
|
|
|
|
end do
|
|
|
|
end do
|
|
|
@ -492,6 +546,42 @@ module elements
|
|
|
|
return
|
|
|
|
return
|
|
|
|
end subroutine rhombshape
|
|
|
|
end subroutine rhombshape
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
subroutine quad_rhombshape(r,s,t, shape_fun)
|
|
|
|
|
|
|
|
!Shape function for 20 node quadratic rhombohedral elements
|
|
|
|
|
|
|
|
real(kind=8), intent(in) :: r, s, t
|
|
|
|
|
|
|
|
real(kind=8), intent(out) :: shape_fun(:)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!Corner nodes
|
|
|
|
|
|
|
|
shape_fun(1) = (1.0_dp-r)*(1.0_dp-s)*(1.0_dp-t)*(-r-s-t-2)/8.0_dp
|
|
|
|
|
|
|
|
shape_fun(2) = (1.0_dp+r)*(1.0_dp-s)*(1.0_dp-t)*(r-s-t-2)/8.0_dp
|
|
|
|
|
|
|
|
shape_fun(3) = (1.0_dp+r)*(1.0_dp+s)*(1.0_dp-t)*(r+s-t-2)/8.0_dp
|
|
|
|
|
|
|
|
shape_fun(4) = (1.0_dp-r)*(1.0_dp+s)*(1.0_dp-t)*(-r+s-t-2)/8.0_dp
|
|
|
|
|
|
|
|
shape_fun(5) = (1.0_dp-r)*(1.0_dp-s)*(1.0_dp+t)*(-r-s+t-2)/8.0_dp
|
|
|
|
|
|
|
|
shape_fun(6) = (1.0_dp+r)*(1.0_dp-s)*(1.0_dp+t)*(r-s+t-2)/8.0_dp
|
|
|
|
|
|
|
|
shape_fun(7) = (1.0_dp+r)*(1.0_dp+s)*(1.0_dp+t)*(r+s+t-2)/8.0_dp
|
|
|
|
|
|
|
|
shape_fun(8) = (1.0_dp-r)*(1.0_dp+s)*(1.0_dp+t)*(-r+s+t-2)/8.0_dp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!Side nodes, first node r is zero
|
|
|
|
|
|
|
|
shape_fun(9) = (1-r*r)*(1-s)*(1-t)/4.0_dp
|
|
|
|
|
|
|
|
shape_fun(11) = (1-r*r)*(1+s)*(1-t)/4.0_dp
|
|
|
|
|
|
|
|
shape_fun(17) = (1-r*r)*(1-s)*(1+t)/4.0_dp
|
|
|
|
|
|
|
|
shape_fun(19) = (1-r*r)*(1+s)*(1+t)/4.0_dp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!node s is zero
|
|
|
|
|
|
|
|
shape_fun(10) = (1+r)*(1-s*s)*(1-t)/4.0_dp
|
|
|
|
|
|
|
|
shape_fun(12) = (1-r)*(1-s*s)*(1-t)/4.0_dp
|
|
|
|
|
|
|
|
shape_fun(18) = (1+r)*(1-s*s)*(1+t)/4.0_dp
|
|
|
|
|
|
|
|
shape_fun(20) = (1-r)*(1-s*s)*(1+t)/4.0_dp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!node t is zero
|
|
|
|
|
|
|
|
shape_fun(13) = (1-r)*(1-s)*(1-t*t)/4.0_dp
|
|
|
|
|
|
|
|
shape_fun(14) = (1+r)*(1-s)*(1-t*t)/4.0_dp
|
|
|
|
|
|
|
|
shape_fun(15) = (1+r)*(1+s)*(1-t*t)/4.0_dp
|
|
|
|
|
|
|
|
shape_fun(16) = (1-r)*(1+s)*(1-t*t)/4.0_dp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
end subroutine quad_rhombshape
|
|
|
|
|
|
|
|
|
|
|
|
subroutine delete_atoms(num, in_index)
|
|
|
|
subroutine delete_atoms(num, in_index)
|
|
|
|
!This subroutine deletes atoms from the atom arrays
|
|
|
|
!This subroutine deletes atoms from the atom arrays
|
|
|
|
integer, intent(in) :: num
|
|
|
|
integer, intent(in) :: num
|
|
|
@ -624,6 +714,9 @@ do i = 1, atom_num
|
|
|
|
else if(trim(adjustl(pos_string)) == '-inf') then
|
|
|
|
else if(trim(adjustl(pos_string)) == '-inf') then
|
|
|
|
pos=box_bd(2*i-1)
|
|
|
|
pos=box_bd(2*i-1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else if(trim(adjustl(pos_string)) == 'mid') then
|
|
|
|
|
|
|
|
pos=(box_bd(2*i)+box_bd(2*i-1))/2
|
|
|
|
|
|
|
|
|
|
|
|
else if (trim(adjustl(pos_string)) == 'rand') then
|
|
|
|
else if (trim(adjustl(pos_string)) == 'rand') then
|
|
|
|
call random_number(rand)
|
|
|
|
call random_number(rand)
|
|
|
|
pos = (box_bd(2*i)-box_bd(2*i-1))*rand + box_bd(2*i-1)
|
|
|
|
pos = (box_bd(2*i)-box_bd(2*i-1))*rand + box_bd(2*i-1)
|
|
|
@ -647,7 +740,6 @@ do i = 1, atom_num
|
|
|
|
end do
|
|
|
|
end do
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
|
|
read(cone, *) face
|
|
|
|
|
|
|
|
if ((face < 1).or.(face > 6)) stop "Current face number must be 1,2,3,4,5,6. Please check documentation"
|
|
|
|
if ((face < 1).or.(face > 6)) stop "Current face number must be 1,2,3,4,5,6. Please check documentation"
|
|
|
|
!Now get the position
|
|
|
|
!Now get the position
|
|
|
|
call offset_pos(ele, face, rand_ele_pos)
|
|
|
|
call offset_pos(ele, face, rand_ele_pos)
|
|
|
@ -670,6 +762,15 @@ do i = 1, atom_num
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
pos = box_bd(2*i) - pos
|
|
|
|
pos = box_bd(2*i) - pos
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else if ((index(pos_string,'-') > 0).and.(index(pos_string,'mid')>0)) then
|
|
|
|
|
|
|
|
!Now extract the number we are reducing from midinity
|
|
|
|
|
|
|
|
if(index(pos_string,'mid') < index(pos_string,'-')) then
|
|
|
|
|
|
|
|
read(pos_string(index(pos_string,'-')+1:), *, iostat=iospara) pos
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
read(pos_string(1:index(pos_string,'-')-1), *, iostat=iospara) pos
|
|
|
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
pos = (box_bd(2*i)+box_bd(2*i-1))/2.0_dp - pos
|
|
|
|
|
|
|
|
|
|
|
|
else if ((index(pos_string,'+') > 0).and.(index(pos_string,'inf')>0)) then
|
|
|
|
else if ((index(pos_string,'+') > 0).and.(index(pos_string,'inf')>0)) then
|
|
|
|
!Now extract the number we are reducing from infinity
|
|
|
|
!Now extract the number we are reducing from infinity
|
|
|
|
if(index(pos_string,'inf') < index(pos_string,'+')) then
|
|
|
|
if(index(pos_string,'inf') < index(pos_string,'+')) then
|
|
|
@ -679,6 +780,15 @@ do i = 1, atom_num
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
pos = box_bd(2*i-1) + pos
|
|
|
|
pos = box_bd(2*i-1) + pos
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else if ((index(pos_string,'+') > 0).and.(index(pos_string,'mid')>0)) then
|
|
|
|
|
|
|
|
!Now extract the number we are reducing from midinity
|
|
|
|
|
|
|
|
if(index(pos_string,'mid') < index(pos_string,'+')) then
|
|
|
|
|
|
|
|
read(pos_string(index(pos_string,'+')+1:), *, iostat=iospara) pos
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
read(pos_string(1:index(pos_string,'+')-1), *, iostat=iospara) pos
|
|
|
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
pos = (box_bd(2*i)+box_bd(2*i-1))/2.0_dp + pos
|
|
|
|
|
|
|
|
|
|
|
|
else if ((index(pos_string,'*') > 0).and.(index(pos_string,'inf')>0)) then
|
|
|
|
else if ((index(pos_string,'*') > 0).and.(index(pos_string,'inf')>0)) then
|
|
|
|
!Now extract the number we are reducing from infinity
|
|
|
|
!Now extract the number we are reducing from infinity
|
|
|
|
if(index(pos_string,'inf') < index(pos_string,'*')) then
|
|
|
|
if(index(pos_string,'inf') < index(pos_string,'*')) then
|
|
|
@ -809,6 +919,7 @@ do i = 1, atom_num
|
|
|
|
integer, intent(in) :: n,m !n-size of element arrays, m-size of atom arrays
|
|
|
|
integer, intent(in) :: n,m !n-size of element arrays, m-size of atom arrays
|
|
|
|
integer :: allostat
|
|
|
|
integer :: allostat
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print *, max_ng_node
|
|
|
|
!Allocate element arrays
|
|
|
|
!Allocate element arrays
|
|
|
|
if (n > 0) then
|
|
|
|
if (n > 0) then
|
|
|
|
if (allocated(force_node)) then
|
|
|
|
if (allocated(force_node)) then
|
|
|
|