@ -8,7 +8,7 @@ module opt_disl
use box
implicit none
integer :: vloop_size ! Number of atoms to remove in planar vacancy cluster
real ( kind = dp ) , dimension ( 3 ) :: line , slip_plane , centroid ! dislocation line , slip plane vectors , centroid ,
real ( kind = dp ) :: burgers ( 3 ) ! burgers vector of loop
real ( kind = dp ) :: poisson , char_angle , lattice_parameter ! Poisson ratio and character angle , lattice_parameter for burgers vector
@ -37,6 +37,9 @@ module opt_disl
case ( '-disloop' )
call parse_disloop ( arg_pos )
call disloop
case ( '-vacancydisloop' )
call parse_vacancydisloop ( arg_pos )
call vacancy_disloop
end select
end subroutine dislocation
@ -210,7 +213,7 @@ module opt_disl
arg_pos = arg_pos + 1
loop_radius = 0
call get_command_argument ( arg_pos , textholder , arglen )
if ( arglen == 0 ) STOP "Missing loop_ size in disloop command"
if ( arglen == 0 ) STOP "Missing loop_ radius in disloop command"
read ( textholder , * ) loop_radius
do i = 1 , 3
@ -470,61 +473,113 @@ module opt_disl
!
END FUNCTION DisloSeg_displacement_iso
!
subroutine parse_vacancydisloop ( arg_pos )
! This subroutine parses the disloop command
integer , intent ( inout ) :: arg_pos
integer :: i , arglen
character ( len = 100 ) :: textholder
! Parse all of the commands
arg_pos = arg_pos + 1
loop_normal = ' '
call get_command_argument ( arg_pos , loop_normal , arglen )
if ( arglen == 0 ) STOP "Missing loop_normal in disloop command"
! Convert the loop_normal to the dimension
select case ( loop_normal )
case ( 'x' , 'X' , 'y' , 'Y' , 'z' , 'Z' )
continue
case default
print * , "Dimension argument must either be x, y, or z not" , loop_normal
stop 3
end select
arg_pos = arg_pos + 1
loop_radius = 0
call get_command_argument ( arg_pos , textholder , arglen )
if ( arglen == 0 ) STOP "Missing loop_radius in disloop command"
read ( textholder , * ) loop_radius
do i = 1 , 3
arg_pos = arg_pos + 1
call get_command_argument ( arg_pos , textholder , arglen )
if ( arglen == 0 ) STOP "Missing centroid in disloop command"
call parse_pos ( i , textholder , centroid ( i ) )
end do
arg_pos = arg_pos + 1
! Now check to make sure that the dimension selected is actually a 1 1 1 direction .
! call in_sub_box ( centroid , sbox )
! if ( . not . ( ( abs ( sub_box_ori ( loop_normal , 1 , sbox ) ) == abs ( sub_box_ori ( loop_normal , 2 , sbox ) ) ) . and . &
! ( abs ( sub_box_ori ( loop_normal , 2 , sbox ) ) == abs ( sub_box_ori ( loop_normal , 3 , sbox ) ) ) . and . &
! ( abs ( sub_box_ori ( loop_normal , 3 , sbox ) ) == abs ( sub_box_ori ( loop_normal , 1 , sbox ) ) ) ) ) then
! print * , "The selected dimension " , loop_normal , " for sub_box " , sbox , " is " , &
! sub_box_ori ( loop_normal , : , sbox ) , " which is not in the (111) family of planes"
! STOP 3
! end if
end subroutine parse_vacancydisloop
! This code simply creates a planar vacancy cluster and does not apply the dislocation loop displacement field .
! subroutine disloop
! ! This subroutine actually creates the dislocation loop .
! real ( kind = dp ) :: neighbor_dis ( loop_size ) , temp_box ( 6 ) , dis
! integer :: i , j , index ( loop_size )
! neighbor_dis ( : ) = HUGE ( 1.0_dp )
! index ( : ) = 0
! ! First find the nearest atom to the centroid
! do i = 1 , atom_num
! if ( norm2 ( r_atom ( : , i ) - centroid ) < neighbor_dis ( 1 ) ) then
! neighbor_dis ( 1 ) = norm2 ( r_atom ( : , i ) - centroid )
! index ( 1 ) = i
! end if
! end do
! ! Define a new box , this box tries to isolate all atoms on the plane of the atom
! ! closest to the user defined centroid .
! temp_box ( : ) = box_bd ( : )
! temp_box ( 2 * loop_normal ) = r_atom ( loop_normal , index ( 1 ) ) + 1 0.0_dp ** ( - 2.0_dp )
! temp_box ( 2 * loop_normal - 1 ) = r_atom ( loop_normal , index ( 1 ) ) - 1 0.0_dp ** ( - 2.0_dp )
! ! Now reset the list for the scanning algorithm
! index ( 1 ) = 0
! neighbor_dis ( 1 ) = HUGE ( 1.0_dp )
! ! Now scan over all atoms again and find the closest loop_size number of atoms to the initial atom
! ! that reside on the same plane .
! do i = 1 , atom_num
! ! Check to see if it is on the same plane
! if ( in_block_bd ( r_atom ( : , i ) , temp_box ) ) then
! dis = norm2 ( r_atom ( : , i ) - centroid )
! do j = 1 , loop_size
! ! Check to see if it is closer than other atoms
! if ( dis < neighbor_dis ( j ) ) then
! ! Move values in the neighbor array and add the new neighbor
! if ( j < loop_size ) then
! neighbor_dis ( j + 1 : loop_size ) = neighbor_dis ( j : loop_size - 1 )
! index ( j + 1 : loop_size ) = index ( j : loop_size - 1 )
! end if
! neighbor_dis ( j ) = dis
! index ( j ) = i
! exit
! end if
! end do
! end if
! end do
! ! Now delete the atoms
! call delete_atoms ( loop_size , index )
! return
! end subroutine disloop
subroutine vacancy_disloop
! This subroutine actually creates the dislocation loop .
real ( kind = dp ) :: neighbor_dis , temp_box ( 6 ) , dis , normal_dim
integer :: i , j , index , delete_num , delete_index ( atom_num )
neighbor_dis = HUGE ( 1.0_dp )
index = 0
! First find the nearest atom to the centroid
do i = 1 , atom_num
if ( norm2 ( r_atom ( : , i ) - centroid ) < neighbor_dis ) then
neighbor_dis = norm2 ( r_atom ( : , i ) - centroid )
index = i
end if
end do
! Define a new box , this box tries to isolate all atoms on the plane of the atom
select case ( trim ( adjustl ( loop_normal ) ) )
case ( 'x' , 'X' )
normal_dim = 1
case ( 'y' , 'Y' )
normal_dim = 2
case ( 'z' , 'Z' )
normal_dim = 3
end select
temp_box ( : ) = box_bd ( : )
temp_box ( 2 * normal_dim ) = r_atom ( normal_dim , index ) + 1 0.0_dp ** ( - 2.0_dp )
temp_box ( 2 * normal_dim - 1 ) = r_atom ( normal_dim , index ) - 1 0.0_dp ** ( - 2.0_dp )
! Define the new centroid starting on the nearest atom
centroid = r_atom ( : , index )
! Now reset the list for the scanning algorithm
! Now scan over all atoms again and find the closest vloop_size number of atoms to the initial atom
! that reside on the same plane .
delete_num = 0
do i = 1 , atom_num
! Check to see if it is on the same plane
if ( in_block_bd ( r_atom ( : , i ) , temp_box ) ) then
dis = norm2 ( r_atom ( : , i ) - centroid )
! Check to see if it is within the loop radius , if so then add it to the delete list
if ( dis < loop_radius ) then
delete_num = delete_num + 1
delete_index ( delete_num ) = i
end if
end if
end do
! Now delete the atoms
call delete_atoms ( delete_num , delete_index ( 1 : delete_num ) )
return
end subroutine vacancy_disloop
end module opt_disl