Added group option and shift command

master
Alex 5 years ago
parent f80045058f
commit 347b73054b

@ -153,4 +153,23 @@ This option deletes vacancies on a plane which when minimized should result in a
`bx by bz` - The burgers vector for the dislocation
`poisson` - Poisson ratio for continuum solution
`poisson` - Poisson ratio for continuum solution
### Option Group
`-group select_type group_shape shape_arguments additional keywords`
This option selects a group of either elements, nodes, atoms and applies some transformation to them.
`select_type` - Either `nodes`, `atoms`, `elements`, `nodes/atoms`, `all`. When using the option `nodes` only nodes which are within the group are selected, `elements` selects elements based on whether the element center is within the group, `nodes/atoms` selects both nodes and atoms for the group. `all` selects elements based on the element center and atoms based on their position.
`group_shape` - Specifies what shape the group takes and dictates which options must be passed. Each shape requires different arguments and these arguments are represented by the placeholder `shape_arguments`. The accepted group shapes and arguments are below:
*Block:*
`-group nodes block xlo xhi ylo yhi zlo zhi`
This selects a group residing in a block with edges perpendicular to the simulation cell. The block boundaries are given by `xlo xhi ylo yhi zlo zhi`.
`additional keywords`- Represents the various transformations which can be performed on a group. These additional keywords are given below.

@ -2,8 +2,8 @@ FC=ifort
FFLAGS=-mcmodel=large -g -O0 -stand f08 -fpe0 -traceback -check bounds,uninit -warn all -implicitnone -no-wrap-margin
#FFLAGS=-mcmodel=large -Ofast -no-wrap-margin
MODES=mode_create.o mode_merge.o mode_convert.o
OPTIONS=opt_disl.o
OBJECTS=main.o elements.o io.o subroutines.o functions.o atoms.o call_mode.o box.o call_option.o $(MODES) $(OPTIONS)
OPTIONS=opt_disl.o opt_group.o
OBJECTS=main.o elements.o io.o subroutines.o functions.o atoms.o call_mode.o box.o $(MODES) $(OPTIONS) call_option.o
.SUFFIXES:
.SUFFIXES: .c .f .f90 .F90 .o
@ -38,6 +38,6 @@ atoms.o subroutines.o testfuncs.o box.o : functions.o
main.o io.o $(MODES) $(OPTIONS) : elements.o
call_mode.o : $(MODES)
call_option.o : $(OPTIONS)
$(MODES) io.o: atoms.o box.o
$(MODES) $(OPTIONS) io.o : atoms.o box.o
$(MODES) main.o : io.o
testfuncs.o elements.o mode_create.o opt_disl.o: subroutines.o
testfuncs.o elements.o mode_create.o $(OPTIONS): subroutines.o

@ -399,6 +399,8 @@ module io
select case(max_ng_node)
case(8)
interp_max = (max_esize)**3
case default
interp_max = 0
end select
write(11,20) interp_max
write(11,3) node_num

@ -0,0 +1,200 @@
module opt_group
!This module contains all code associated with dislocations
use parameters
use elements
use subroutines
use box
implicit none
integer :: group_ele_num, group_atom_num
character(len=15) :: type, shape !Type indicates what element type is selected and shape is the group shape
real(kind=dp) :: block_bd(6), disp_vec(3)
logical :: displace, wrap
integer, allocatable :: element_index(:), atom_index(:)
public
contains
subroutine group(arg_pos)
!Main calling function for the group option
integer, intent(inout) :: arg_pos
group_ele_num = 0
group_atom_num = 0
if(allocated(element_index)) deallocate(element_index)
if(allocated(atom_index)) deallocate(atom_index)
call parse_group(arg_pos)
call get_group
!Now call the transformation functions for the group
if(displace) call displace_group
end subroutine group
subroutine parse_group(arg_pos)
!Parse the group command
integer, intent(inout) :: arg_pos
integer :: i,arglen
character(len=100) :: textholder
!Parse type and shape command
arg_pos = arg_pos + 1
call get_command_argument(arg_pos, type, arglen)
if (arglen==0) STOP "Missing select_type in group command"
select case(trim(adjustl(type)))
case('atoms', 'elements', 'both')
continue
case default
print *, "Select_type ", trim(adjustl(type)), " is not an accept group selection criteria. ", &
"Please select from atoms, nodes, or both."
end select
arg_pos = arg_pos + 1
call get_command_argument(arg_pos, shape, 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)))
case('block')
do i= 1, 6
arg_pos = arg_pos + 1
call get_command_argument(arg_pos, textholder, arglen)
if (arglen==0) STOP "Missing block boundary in dislgen command"
call parse_pos(int((i+1)/2), textholder, block_bd(i))
end do
case default
print *, "Group shape ", trim(adjustl(shape)), " is not currently accepted. Please check documentation ", &
"for accepted group shapes."
end select
!Now parse the additional options which may be present
do while(.true.)
if(arg_pos > command_argument_count()) exit
!Pull out the next argument which should either be a keyword or an option
arg_pos=arg_pos+1
call get_command_argument(arg_pos, textholder)
textholder=adjustl(textholder)
!Choose what to based on what the option string is
select case(trim(textholder))
case('displace')
displace = .true.
do i = 1,3
arg_pos = arg_pos + 1
call get_command_argument(arg_pos, textholder, arglen)
if (arglen==0) stop "Missing vector component for shift command"
read(textholder, *) disp_vec(i)
end do
case('wrap')
wrap = .true.
case default
!If it isn't an available option to opt_disl then we just exit
exit
end select
end do
end subroutine parse_group
subroutine get_group
!This subroutine finds all elements and/or atoms within the group boundaries
!specified by the user.
integer :: i, inod, ibasis
integer, allocatable :: resize_array(:)
real(kind=dp) :: r_center(3)
select case(trim(adjustl(shape)))
case('block')
!Allocate variables to arbitrary size
allocate(element_index(1024), atom_index(1024))
!Check the type to see whether we need to find the elements within the group
select case(trim(adjustl(type)))
case('elements', 'both')
do i = 1, ele_num
r_center(:) = 0.0_dp
do inod = 1, ng_node(lat_ele(i))
do ibasis = 1, basisnum(lat_ele(i))
r_center = r_center + r_node(:,ibasis,inod,i)/(basisnum(lat_ele(i))*ng_node(lat_ele(i)))
end do
end do
if (in_block_bd(r_center, block_bd)) then
group_ele_num = group_ele_num + 1
if(group_ele_num > size(element_index)) then
allocate(resize_array(size(element_index) + 1024))
resize_array(1:group_ele_num-1) = element_index
resize_array(group_ele_num:) = 0
call move_alloc(resize_array, element_index)
end if
element_index(group_ele_num) = i
end if
end do
end select
!Check the type to see if we need to find the atoms within the group
select case(trim(adjustl(type)))
case('atoms','both')
do i = 1, atom_num
if(in_block_bd(r_atom(:,i),block_bd)) then
group_atom_num = group_atom_num + 1
if (group_atom_num > size(atom_index)) then
allocate(resize_array(size(atom_index) + 1024))
resize_array(1:group_atom_num -1) = atom_index
resize_array(group_atom_num:) = 0
call move_alloc(resize_array, atom_index)
end if
atom_index(group_atom_num) = i
end if
end do
end select
end select
end subroutine get_group
subroutine displace_group
!This subroutine applies a displacement to elements/atoms in the groups
integer :: i, inod, ibasis
!Displace atoms
do i = 1, group_atom_num
r_atom(:,atom_index(i)) = r_atom(:,atom_index(i)) + disp_vec
end do
!Displace elements
do i = 1, group_ele_num
do inod = 1, ng_node(lat_ele(element_index(i)))
do ibasis = 1, basisnum(lat_ele(element_index(i)))
r_node(:,ibasis,inod,element_index(i)) = r_node(:,ibasis,inod,element_index(i)) + disp_vec
end do
end do
end do
!Now either apply periodic boundaries if wrap command was passed or adjust box dimensions
!Now we check if we have to wrap the atoms, nodes are not wrapped. For elements the periodic
!boundary conditions are applied in the actual CAC codes
if(wrap) then
do i = 1, atom_num
call apply_periodic(r_atom(:,i))
end do
!If we don't include the wrap command then we have to increase the size of the box
else
do i = 1,3
if (disp_vec(i) < -lim_zero) then
box_bd(2*i-1) = box_bd(2*i-1) - disp_vec(i)
else if (disp_vec(i) > lim_zero) then
box_bd(2*i) = box_bd(2*i) + disp_vec(i)
end if
end do
end if
end subroutine displace_group
end module opt_group

@ -178,6 +178,8 @@ module subroutines
real(kind=dp), intent(out) :: pos !The output parsed position value
integer :: iospara
iospara = 0
if(trim(adjustl(pos_string)) == 'inf') then
pos=box_bd(2*i)
else if(trim(adjustl(pos_string)) == '-inf') then
@ -258,12 +260,13 @@ module subroutines
real(kind=dp), dimension(3), intent(inout) :: r
integer :: j
real(kind=dp) ::box_len
do j = 1, 3
box_len = box_bd(2*j) - box_bd(2*j-1)
if (r(j) > box_bd(2*j)) then
r(j) = r(j) - box_bd(2*j)
r(j) = r(j) - box_len
else if (r(j) < box_bd(2*j-1)) then
r(j) = r(j) + box_bd(2*j-1)
r(j) = r(j) + box_len
end if
end do
end subroutine

Loading…
Cancel
Save