From fc2035074825bf19cbba6f46eb3dd3b0b28d6bad Mon Sep 17 00:00:00 2001 From: Alex Selimov Date: Fri, 13 Mar 2020 15:55:45 -0400 Subject: [PATCH] vacancydisloop option added --- README.md | 12 +++- src/Makefile | 4 +- src/call_option.f90 | 2 +- src/opt_disl.f90 | 169 +++++++++++++++++++++++++++++--------------- 4 files changed, 125 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index d387a8d..346fa58 100644 --- a/README.md +++ b/README.md @@ -165,9 +165,9 @@ This options adds an arbitrarily oriented dislocation into your model based on u -disloop loop_normal radius x y z bx by bz poisson ```` -This option deletes vacancies on a plane which when minimized should result in a dislocation loop structure. The arguments are below: +This option imposes the displacement field for a dislocation in order to create a loop. This loop is unstable and will close if stress isn't applied. -`dim` - The box dimension which defines the normal to the loop plane. As of now this dimension must be a closed back direction, meaning that for fcc a box dimension has to be of the (111) family of planes. Either `x`, `y`, or `z`. +`loop_normal` - The box dimension which defines the normal to the loop plane. As of now this dimension must be a closed back direction, meaning that for fcc a box dimension has to be of the (111) family of planes. Either `x`, `y`, or `z`. `n` - The number of atoms to delete on the loop plane @@ -177,6 +177,14 @@ This option deletes vacancies on a plane which when minimized should result in a `poisson` - Poisson ratio for continuum solution +### Option vacancy_disloop + +``` +-vacancydisloop loop_normal radius x y z +``` + +This option creates a circular planar vacancy cluster of radius `radius` normal to the `loop_normal` centered on position `x y z`. Upon relaxing or energy minimization this cluster should become a prismatic dislocation loop. + ### Option Group `-group select_type group_shape shape_arguments additional keywords` diff --git a/src/Makefile b/src/Makefile index 2e314ca..9a3fced 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,6 +1,6 @@ FC=ifort -#FFLAGS=-mcmodel=large -g -O0 -stand f08 -fpe0 -traceback -check bounds,uninit -warn all -implicitnone -no-wrap-margin -heap-arrays -FFLAGS=-mcmodel=large -Ofast -no-wrap-margin -heap-arrays +FFLAGS=-mcmodel=large -g -O0 -stand f08 -fpe0 -traceback -check bounds,uninit -warn all -implicitnone -no-wrap-margin -heap-arrays +#FFLAGS=-mcmodel=large -Ofast -no-wrap-margin -heap-arrays MODES=mode_create.o mode_merge.o mode_convert.o OPTIONS=opt_disl.o opt_group.o opt_orient.o opt_delete.o OBJECTS=main.o elements.o io.o subroutines.o functions.o atoms.o call_mode.o box.o $(MODES) $(OPTIONS) call_option.o diff --git a/src/call_option.f90 b/src/call_option.f90 index ac31b77..73cd1de 100644 --- a/src/call_option.f90 +++ b/src/call_option.f90 @@ -11,7 +11,7 @@ subroutine call_option(option, arg_pos) character(len=100), intent(in) :: option select case(trim(adjustl(option))) - case('-dislgen', '-disloop') + case('-dislgen', '-disloop','-vacancydisloop') call dislocation(option, arg_pos) case('-group') call group(arg_pos) diff --git a/src/opt_disl.f90 b/src/opt_disl.f90 index 4281d12..776b3c5 100644 --- a/src/opt_disl.f90 +++ b/src/opt_disl.f90 @@ -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)) + 10.0_dp**(-2.0_dp) - ! temp_box(2*loop_normal-1) = r_atom(loop_normal,index(1)) - 10.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) + 10.0_dp**(-2.0_dp) + temp_box(2*normal_dim-1) = r_atom(normal_dim,index) - 10.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 \ No newline at end of file