|
|
|
@ -6,18 +6,23 @@ module mode_merge
|
|
|
|
|
use io
|
|
|
|
|
use subroutines
|
|
|
|
|
use elements
|
|
|
|
|
use neighbors
|
|
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
|
|
|
|
|
character(len=4) :: dim
|
|
|
|
|
integer :: in_num, new_starts(2)
|
|
|
|
|
real(kind=dp) :: shift_vec(3)
|
|
|
|
|
logical :: shift_flag
|
|
|
|
|
real(kind=dp) :: shift_vec(3), replace_vec(3)
|
|
|
|
|
character(len=100) :: replace_str(3)
|
|
|
|
|
logical :: shift_flag, replace_flag
|
|
|
|
|
real(kind=dp), private, save :: rc_off
|
|
|
|
|
|
|
|
|
|
public
|
|
|
|
|
contains
|
|
|
|
|
subroutine merge(arg_pos)
|
|
|
|
|
|
|
|
|
|
integer, intent(out) :: arg_pos
|
|
|
|
|
integer :: i
|
|
|
|
|
integer :: i, j
|
|
|
|
|
real(kind=dp) :: displace(3), temp_box_bd(6)
|
|
|
|
|
|
|
|
|
|
print *, '-----------------------Mode Merge---------------------------'
|
|
|
|
@ -55,8 +60,19 @@ module mode_merge
|
|
|
|
|
call read_in(i, displace, temp_box_bd)
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(shift_flag) call shift(new_starts, i)
|
|
|
|
|
|
|
|
|
|
if(replace_flag.and.(i>1)) then
|
|
|
|
|
!Parse the replace vector
|
|
|
|
|
do j = 1, 3
|
|
|
|
|
call parse_pos(j, replace_str(j), replace_vec(j))
|
|
|
|
|
end do
|
|
|
|
|
call replace(new_starts, temp_box_bd)
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
!Now reset tags
|
|
|
|
|
do i = 1, atom_num
|
|
|
|
@ -122,6 +138,17 @@ module mode_merge
|
|
|
|
|
if (arglen==0) stop "Missing vector component for shift command"
|
|
|
|
|
read(textholder, *) shift_vec(i)
|
|
|
|
|
end do
|
|
|
|
|
case('replace')
|
|
|
|
|
replace_flag = .true.
|
|
|
|
|
do i = 1,3
|
|
|
|
|
arg_pos = arg_pos + 1
|
|
|
|
|
call get_command_argument(arg_pos, replace_str(i), arglen)
|
|
|
|
|
if (arglen==0) stop "Missing vector component for shift command"
|
|
|
|
|
end do
|
|
|
|
|
arg_pos = arg_pos+1
|
|
|
|
|
call get_command_argument(arg_pos, textholder, arglen)
|
|
|
|
|
read(textholder,*) rc_off
|
|
|
|
|
|
|
|
|
|
case default
|
|
|
|
|
!If it isn't an available option to mode merge then we just exit
|
|
|
|
|
exit
|
|
|
|
@ -176,4 +203,147 @@ module mode_merge
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
end subroutine shift
|
|
|
|
|
|
|
|
|
|
subroutine replace(array_start, rbox_bd)
|
|
|
|
|
integer, intent(in) :: array_start(2)
|
|
|
|
|
real(kind = dp), intent(in) :: rbox_bd(6)
|
|
|
|
|
|
|
|
|
|
integer :: ibasis, inod, del_num, del_index(atom_num), nump_ele, interp_start
|
|
|
|
|
integer :: j, ie, type_interp(max_basisnum*max_esize**3), add_atom_num, orig_atom_num, m, n, o, esize, &
|
|
|
|
|
ele(3,8), new_ele_num, vlat(3), added_points
|
|
|
|
|
real(kind=dp) :: r_interp(3, max_basisnum*max_esize**3), rfill(3,max_basisnum,max_ng_node), ravg(3), ratom(3,max_basisnum)
|
|
|
|
|
logical :: in_bd, lat_points(max_esize, max_esize, max_esize)
|
|
|
|
|
real(kind=dp) :: del_bd(6)
|
|
|
|
|
integer :: i, c(3), ci, cj, ck, num_nei, nei, delete_num
|
|
|
|
|
|
|
|
|
|
!These are the variables containing the cell list information
|
|
|
|
|
integer, dimension(3) :: cell_num
|
|
|
|
|
integer, allocatable :: num_in_cell(:,:,:), which_cell(:,:)
|
|
|
|
|
integer, allocatable :: cell_list(:,:,:,:)
|
|
|
|
|
|
|
|
|
|
!First apply the replace vec to all new nodes and elements
|
|
|
|
|
do i = array_start(1), atom_num
|
|
|
|
|
r_atom(:,i) = r_atom(:, i) + replace_vec
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
do i = array_start(2), ele_num
|
|
|
|
|
do inod = 1, ng_node(lat_ele(i))
|
|
|
|
|
do ibasis=1, basisnum(lat_ele(i))
|
|
|
|
|
r_node(:, ibasis,inod, i) = r_node(:, ibasis,inod, i) + replace_vec
|
|
|
|
|
end do
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
!Calculate new boundary
|
|
|
|
|
do i = 1, 6
|
|
|
|
|
del_bd(i) = rbox_bd(i) + replace_vec((i-1)/2 + 1)
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
del_num = 0
|
|
|
|
|
del_index=0
|
|
|
|
|
interp_start = atom_num +1
|
|
|
|
|
!Now loop over all old elements,
|
|
|
|
|
do ie = 1, array_start(2)-1
|
|
|
|
|
!If any element points are within the boundary then we run the refine code
|
|
|
|
|
if(ele_in_bounds(del_bd, type_ele(ie), size_ele(ie), lat_ele(ie), r_node(:,:,:,ie))) then
|
|
|
|
|
added_points=0
|
|
|
|
|
del_num = del_num + 1
|
|
|
|
|
del_index(del_num) = ie
|
|
|
|
|
|
|
|
|
|
!Find all possible elements that we can make while making sure they aren't in the group
|
|
|
|
|
lat_points(1:size_ele(ie),1:size_ele(ie),1:size_ele(ie)) = .true.
|
|
|
|
|
|
|
|
|
|
!Now add the leftover lattice points as atoms, only if they aren't within the new boundaries
|
|
|
|
|
do o = 1, size_ele(ie)
|
|
|
|
|
do n = 1, size_ele(ie)
|
|
|
|
|
do m = 1, size_ele(ie)
|
|
|
|
|
if(lat_points(m,n,o)) then
|
|
|
|
|
call get_interp_pos(m,n,o, ie, ratom(:,:))
|
|
|
|
|
do ibasis = 1, basisnum(lat_ele(ie))
|
|
|
|
|
call apply_periodic(ratom(:,ibasis))
|
|
|
|
|
added_points=added_points + 1
|
|
|
|
|
call add_atom(0, basis_type(ibasis,lat_ele(ie)), sbox_ele(ie), ratom(:,ibasis))
|
|
|
|
|
end do
|
|
|
|
|
end if
|
|
|
|
|
end do
|
|
|
|
|
end do
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
if (added_points /= (size_ele(ie)**3)) then
|
|
|
|
|
print *, "Element ", ie, " is refined incorrectly in refinefill"
|
|
|
|
|
end if
|
|
|
|
|
end if
|
|
|
|
|
end do
|
|
|
|
|
|
|
|
|
|
!Once all atoms are added we delete all of the elements
|
|
|
|
|
call delete_elements(del_num, del_index)
|
|
|
|
|
|
|
|
|
|
!Now delete overlapping atoms
|
|
|
|
|
allocate(which_cell(3,atom_num))
|
|
|
|
|
|
|
|
|
|
!First pass the atom list and atom num to the algorithm which builds the cell list
|
|
|
|
|
print *, rc_off
|
|
|
|
|
call build_cell_list(atom_num, r_atom, 4*rc_off, cell_num, num_in_cell, cell_list, which_cell)
|
|
|
|
|
|
|
|
|
|
!Now loop over every atom and figure out if it has neighbors within the rc_off
|
|
|
|
|
del_num = 0
|
|
|
|
|
atom_loop: do i = 1, atom_num
|
|
|
|
|
|
|
|
|
|
!c is the position of the cell that the atom belongs to
|
|
|
|
|
c = which_cell(:,i)
|
|
|
|
|
|
|
|
|
|
!Check to make sure it hasn't already been deleted
|
|
|
|
|
if(all(c /= 0)) then
|
|
|
|
|
!Now loop over all neighboring cells
|
|
|
|
|
do ci = -1, 1, 1
|
|
|
|
|
do cj = -1, 1, 1
|
|
|
|
|
do ck = -1, 1, 1
|
|
|
|
|
|
|
|
|
|
if (any((c + (/ ck, cj, ci /)) == 0)) cycle
|
|
|
|
|
|
|
|
|
|
if( (c(1) + ck > cell_num(1)).or.(c(2) + cj > cell_num(2)).or. &
|
|
|
|
|
(c(3) + ci > cell_num(3))) cycle
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
do num_nei = 1, num_in_cell(c(1) + ck, c(2) + cj, c(3) + ci)
|
|
|
|
|
nei = cell_list(num_nei,c(1) + ck, c(2) + cj, c(3) + ci)
|
|
|
|
|
|
|
|
|
|
!Check to make sure the atom isn't the same index as the atom we are checking
|
|
|
|
|
!and that the neighbor hasn't already been deleted
|
|
|
|
|
if((nei /= i).and.(nei/= 0)) then
|
|
|
|
|
|
|
|
|
|
!Now check to see if it is in the cutoff radius, if it is add it to the delete code
|
|
|
|
|
if (norm2(r_atom(:,nei)-r_atom(:,i)) < rc_off) then
|
|
|
|
|
|
|
|
|
|
del_num = del_num + 1
|
|
|
|
|
|
|
|
|
|
!Make sure to delete the older value
|
|
|
|
|
if( (i < array_start(1)).or.(i > interp_start)) then
|
|
|
|
|
del_index(del_num) = i
|
|
|
|
|
which_cell(:,i) = 0
|
|
|
|
|
cycle atom_loop
|
|
|
|
|
else
|
|
|
|
|
del_index(del_num) = nei
|
|
|
|
|
which_cell(:,nei) = 0
|
|
|
|
|
cell_list(num_nei,c(1) + ck, c(2) + cj, c(3) + ci) = 0
|
|
|
|
|
end if
|
|
|
|
|
end if
|
|
|
|
|
end if
|
|
|
|
|
end do
|
|
|
|
|
end do
|
|
|
|
|
end do
|
|
|
|
|
end do
|
|
|
|
|
end if
|
|
|
|
|
|
|
|
|
|
end do atom_loop
|
|
|
|
|
|
|
|
|
|
print *, "Replace command deletes ", del_num, " atoms"
|
|
|
|
|
!Now delete all the atoms
|
|
|
|
|
call delete_atoms(del_num, del_index(1:del_num))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
end subroutine replace
|
|
|
|
|
|
|
|
|
|
end module mode_merge
|
|
|
|
|