|
|
|
@ -8,9 +8,12 @@ module opt_group
|
|
|
|
|
use box
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
integer :: group_ele_num, group_atom_num, remesh_size,normal, dim1, dim2, random_num, group_type, notsize
|
|
|
|
|
character(len=15) :: type, shape !Type indicates what element type is selected and shape is the group shape
|
|
|
|
|
real(kind=dp) :: block_bd(6), centroid(3), vertices(3,3),disp_vec(3), radius, bwidth, shell_thickness
|
|
|
|
|
integer :: group_ele_num, group_atom_num, remesh_size,normal, dim1, dim2, random_num, group_type, notsize, insert_type, &
|
|
|
|
|
insert_site
|
|
|
|
|
character(len=15) :: type, gshape!Type indicates what element type is selected and shape is the group shape
|
|
|
|
|
real(kind=dp) :: block_bd(6), centroid(3), vertices(3,3),disp_vec(3), radius, bwidth, shell_thickness, insert_conc, &
|
|
|
|
|
insert_lattice
|
|
|
|
|
|
|
|
|
|
logical :: displace, delete, max_remesh, refine, group_nodes, flip, efill, refinefill
|
|
|
|
|
|
|
|
|
|
integer, allocatable :: element_index(:), atom_index(:)
|
|
|
|
@ -29,6 +32,7 @@ module opt_group
|
|
|
|
|
group_ele_num = 0
|
|
|
|
|
group_atom_num = 0
|
|
|
|
|
remesh_size=0
|
|
|
|
|
insert_type = 0
|
|
|
|
|
random_num=0
|
|
|
|
|
group_type=0
|
|
|
|
|
notsize=0
|
|
|
|
@ -74,6 +78,11 @@ module opt_group
|
|
|
|
|
call get_group
|
|
|
|
|
call displace_group
|
|
|
|
|
end if
|
|
|
|
|
if(insert_type > 0) then
|
|
|
|
|
call get_group
|
|
|
|
|
call insert_group
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
end subroutine group
|
|
|
|
|
|
|
|
|
|
subroutine parse_group(arg_pos)
|
|
|
|
@ -97,11 +106,11 @@ module opt_group
|
|
|
|
|
end select
|
|
|
|
|
|
|
|
|
|
arg_pos = arg_pos + 1
|
|
|
|
|
call get_command_argument(arg_pos, shape, arglen)
|
|
|
|
|
call get_command_argument(arg_pos, gshape, arglen)
|
|
|
|
|
if (arglen==0) STOP "Missing group_shape in group command"
|
|
|
|
|
|
|
|
|
|
!Now parse the arguments required by the user selected shape
|
|
|
|
|
select case(trim(adjustl(shape)))
|
|
|
|
|
select case(trim(adjustl(gshape)))
|
|
|
|
|
case('block')
|
|
|
|
|
do i= 1, 6
|
|
|
|
|
arg_pos = arg_pos + 1
|
|
|
|
@ -145,7 +154,7 @@ module opt_group
|
|
|
|
|
vertices(i,2) = box_bd(2*i-1)
|
|
|
|
|
vertices(i,3) = box_bd(2*i-1)
|
|
|
|
|
else
|
|
|
|
|
print *, "bwidth cannot be 0 in wedge shaped group"
|
|
|
|
|
print *, "bwidth cannot be 0 in wedge gshaped group"
|
|
|
|
|
stop 3
|
|
|
|
|
end if
|
|
|
|
|
else if (i == dim2) then
|
|
|
|
@ -368,7 +377,7 @@ module opt_group
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
case default
|
|
|
|
|
print *, "Group shape ", trim(adjustl(shape)), " is not currently accepted. Please check documentation ", &
|
|
|
|
|
print *, "Group shape ", trim(adjustl(gshape)), " is not currently accepted. Please check documentation ", &
|
|
|
|
|
"for accepted group shapes."
|
|
|
|
|
end select
|
|
|
|
|
|
|
|
|
@ -425,8 +434,34 @@ module opt_group
|
|
|
|
|
if(arglen ==0) stop "Missing notsize size"
|
|
|
|
|
read(textholder, *) notsize
|
|
|
|
|
print *, "Ignoring elements with size ", notsize
|
|
|
|
|
case('insert')
|
|
|
|
|
arg_pos=arg_pos+1
|
|
|
|
|
call get_command_argument(arg_pos, textholder, arglen)
|
|
|
|
|
if (arglen==0) stop "Missing element type for insert command"
|
|
|
|
|
call add_atom_type(textholder, insert_type)
|
|
|
|
|
arg_pos=arg_pos + 1
|
|
|
|
|
call get_command_argument(arg_pos, textholder, arglen)
|
|
|
|
|
select case(trim(adjustl(textholder)))
|
|
|
|
|
case('tetra')
|
|
|
|
|
insert_site=1
|
|
|
|
|
case('octa')
|
|
|
|
|
insert_site=2
|
|
|
|
|
case('mixed')
|
|
|
|
|
insert_site=3
|
|
|
|
|
case default
|
|
|
|
|
!If it isn't an available option to opt_disl then we just exit
|
|
|
|
|
print *, "site value must be tetra, octa, or mixed and not ", trim(adjustl(textholder))
|
|
|
|
|
stop 3
|
|
|
|
|
end select
|
|
|
|
|
arg_pos=arg_pos+1
|
|
|
|
|
call get_command_argument(arg_pos, textholder, arglen)
|
|
|
|
|
if(arglen ==0) stop "Missing lattice_type in insert command"
|
|
|
|
|
read(textholder, *) insert_lattice
|
|
|
|
|
arg_pos=arg_pos+1
|
|
|
|
|
call get_command_argument(arg_pos, textholder, arglen)
|
|
|
|
|
if(arglen ==0) stop "Missing concentration in insert command"
|
|
|
|
|
read(textholder, *) insert_conc
|
|
|
|
|
case default
|
|
|
|
|
!If it isn't an available option to opt_group then we just exit
|
|
|
|
|
exit
|
|
|
|
|
end select
|
|
|
|
|
end do
|
|
|
|
@ -439,7 +474,7 @@ module opt_group
|
|
|
|
|
integer, allocatable :: resize_array(:)
|
|
|
|
|
real(kind=dp) :: r_center(3), rand
|
|
|
|
|
|
|
|
|
|
select case(trim(adjustl(shape)))
|
|
|
|
|
select case(trim(adjustl(gshape)))
|
|
|
|
|
case('block')
|
|
|
|
|
print *, "Group has block shape with boundaries: ", block_bd
|
|
|
|
|
case ('wedge')
|
|
|
|
@ -1006,10 +1041,71 @@ module opt_group
|
|
|
|
|
|
|
|
|
|
end subroutine change_group_type
|
|
|
|
|
|
|
|
|
|
subroutine insert_group
|
|
|
|
|
!This code inserts atoms into interstitial sites. This only works on atoms within the group due to the limitations with the
|
|
|
|
|
!Coarse-graining methodology which doesn't allow for concentration fluctuations.
|
|
|
|
|
real(kind=dp) interstitial_sites(3,14), rand, rinsert(3)
|
|
|
|
|
integer :: add_num, i, j, rindex, sindex, ia, rlo, rhi, sbox
|
|
|
|
|
integer, allocatable :: used_sites(:,:)
|
|
|
|
|
|
|
|
|
|
!First save all of the displacement vectors from a lattice site to interstitial site
|
|
|
|
|
!The first 6 are the octohedral sites and the next 8 are the tetrahedral sites
|
|
|
|
|
interstitial_sites= reshape( (/ -0.5_dp, 0.0_dp, 0.0_dp, &
|
|
|
|
|
0.5_dp, 0.0_dp, 0.0_dp, &
|
|
|
|
|
0.0_dp,-0.5_dp, 0.0_dp, &
|
|
|
|
|
0.0_dp, 0.5_dp, 0.0_dp, &
|
|
|
|
|
0.0_dp, 0.0_dp,-0.5_dp, &
|
|
|
|
|
0.0_dp, 0.0_dp, 0.5_dp, &
|
|
|
|
|
-0.25_dp,-0.25_dp,-0.25_dp, &
|
|
|
|
|
-0.25_dp,-0.25_dp, 0.25_dp, &
|
|
|
|
|
-0.25_dp, 0.25_dp,-0.25_dp, &
|
|
|
|
|
-0.25_dp, 0.25_dp, 0.25_dp, &
|
|
|
|
|
0.25_dp,-0.25_dp,-0.25_dp, &
|
|
|
|
|
0.25_dp,-0.25_dp, 0.25_dp, &
|
|
|
|
|
0.25_dp, 0.25_dp,-0.25_dp, &
|
|
|
|
|
0.25_dp, 0.25_dp, 0.25_dp /), &
|
|
|
|
|
shape(interstitial_sites))
|
|
|
|
|
|
|
|
|
|
!First we calculate the number of atoms needed based on the number of atoms in the group and the concentration
|
|
|
|
|
interstitial_sites=interstitial_sites*insert_lattice
|
|
|
|
|
|
|
|
|
|
add_num = (insert_conc*group_atom_num)/(1-insert_conc)
|
|
|
|
|
allocate(used_sites(2,add_num))
|
|
|
|
|
|
|
|
|
|
print *, "Inserting ", add_num, " atoms as atom type ", insert_type
|
|
|
|
|
|
|
|
|
|
!Now set up the random number generator for the desired interstitial type
|
|
|
|
|
select case(insert_site)
|
|
|
|
|
case(1)
|
|
|
|
|
rlo=1
|
|
|
|
|
rhi=6
|
|
|
|
|
case(2)
|
|
|
|
|
rlo=7
|
|
|
|
|
rhi = 14
|
|
|
|
|
case(3)
|
|
|
|
|
rlo=1
|
|
|
|
|
rhi=14
|
|
|
|
|
end select
|
|
|
|
|
|
|
|
|
|
subroutine split_group_elements
|
|
|
|
|
!
|
|
|
|
|
end subroutine split_group_elements
|
|
|
|
|
!Now add the atoms
|
|
|
|
|
i = 1
|
|
|
|
|
addloop:do while ( i < add_num)
|
|
|
|
|
call random_number(rand)
|
|
|
|
|
rindex = int(1+rand*(group_atom_num-1))
|
|
|
|
|
ia=atom_index(rindex)
|
|
|
|
|
call random_number(rand)
|
|
|
|
|
sindex = int(rlo+rand*(rhi-rlo))
|
|
|
|
|
do j = 1, i
|
|
|
|
|
if((ia == used_sites(1,i)).and.(sindex == used_sites(2,i))) cycle addloop
|
|
|
|
|
end do
|
|
|
|
|
rinsert = r_atom(:,ia) + matmul(sub_box_ori(:,:,sbox_atom(ia)),interstitial_sites(:,sindex))
|
|
|
|
|
sbox = sbox_atom(ia)
|
|
|
|
|
call add_atom(0, insert_type, sbox, rinsert)
|
|
|
|
|
used_sites(1,i) = ia
|
|
|
|
|
used_sites(2,i) = sindex
|
|
|
|
|
i = i + 1
|
|
|
|
|
end do addloop
|
|
|
|
|
end subroutine insert_group
|
|
|
|
|
|
|
|
|
|
function in_group(r)
|
|
|
|
|
!This subroutine determines if a point is within the group boundaries
|
|
|
|
@ -1018,7 +1114,7 @@ module opt_group
|
|
|
|
|
|
|
|
|
|
integer :: dim3, i
|
|
|
|
|
logical :: in_group
|
|
|
|
|
select case(trim(adjustl(shape)))
|
|
|
|
|
select case(trim(adjustl(gshape)))
|
|
|
|
|
case('block')
|
|
|
|
|
in_group=in_block_bd(r,block_bd)
|
|
|
|
|
case('wedge')
|
|
|
|
@ -1067,7 +1163,7 @@ module opt_group
|
|
|
|
|
|
|
|
|
|
in_group_ele=.false.
|
|
|
|
|
|
|
|
|
|
if(trim(adjustl(shape)) == 'shell') then
|
|
|
|
|
if(trim(adjustl(gshape)) == 'shell') then
|
|
|
|
|
node_in_out(:) = -1
|
|
|
|
|
!First calculate whether each element node is within the shell region, inside the shell sphere, or outside the
|
|
|
|
|
!shell region
|
|
|
|
@ -1082,13 +1178,13 @@ module opt_group
|
|
|
|
|
exit nodeloop
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
shape ='sphere'
|
|
|
|
|
gshape ='sphere'
|
|
|
|
|
if((in_group(rn(:, ibasis, inod)).neqv.flip).and.(esize/=notsize)) then
|
|
|
|
|
node_in_out(inod) = 1
|
|
|
|
|
else
|
|
|
|
|
node_in_out(inod) = 0
|
|
|
|
|
end if
|
|
|
|
|
shape='shell'
|
|
|
|
|
gshape='shell'
|
|
|
|
|
end do nodeloop
|
|
|
|
|
|
|
|
|
|
!If any nodes are within the shell region, or if the shell region interescts an element then add it to the group
|
|
|
|
|