Working code which picks random position slightly outside element bounds

master
Alex Selimov 5 years ago
parent b847cca4ab
commit 27faeee5ea

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

@ -214,10 +214,10 @@ This command wraps atoms back into the simulation cell as though periodic bounda
**Remesh**
```
remesh esize
remesh esize lattice_parameter lattice_type
```
This command remeshes the atoms/elements within the group to the new element size `esize`. Currently only accepts an `esize` of 2 which refines it to full atomistics. When remeshing to atomistics the group can contain any orientations of elements but when remeshing to different finite elements, the group must contain all atoms/elements with the same orientation.
This command remeshes the atoms/elements within the group to the new element size `esize`. Currently only accepts an `esize` of 2 which refines it to full atomistics. When remeshing to atomistics the group can contain any orientations of elements but when remeshing to different finite elements, the group must contain all atoms/elements with the same orientation. `lattice_parameter` is the lattice parameter for the elements within the group and `lattice_type` is the lattice type (integer) that these new elements will be assigned to.
**Max**
@ -291,3 +291,20 @@ Specifying positions in cacmb can be done through a variety of ways. Examples of
`rand[val1:val2]` - returns a random position that lies within the range
`rande[facenum]` - Returns a random position in an interelement boundary which is offset of the element face `facenum`. Face numbers are based on the which vertices comprise the face. Vertex numbers are shown in the figure below for the primitive fcc unit cell which is what the fcc rhombohedral element is based from. The face numbers are:
Face 1: [1,2,3,4]
Face 2: [1,2,6,5]
Face 3: [2,3,7,6]
Face 4: [3,4,8,7]
Face 5: [1,4,8,5]
Face 6: [5,6,7,8]
Image for vertex numbers is:
![](/home/alexselimov/Documents/CACmb/Numbered_element.png)

@ -64,11 +64,11 @@ module elements
shape(fcc_cell))
!Now we create a list containing the list of vertices needed to describe the 6 cube faces
cubic_faces(:,1) = (/ 1, 4, 8, 5 /)
cubic_faces(:,2) = (/ 2, 3, 7, 6 /)
cubic_faces(:,3) = (/ 1, 2, 6, 5 /)
cubic_faces(:,1) = (/ 1, 2, 3, 4 /)
cubic_faces(:,2) = (/ 1, 2, 6, 5 /)
cubic_faces(:,3) = (/ 2, 3, 7, 6 /)
cubic_faces(:,4) = (/ 3, 4, 8, 7 /)
cubic_faces(:,5) = (/ 1, 2, 3, 4 /)
cubic_faces(:,5) = (/ 1, 4, 8, 5 /)
cubic_faces(:,6) = (/ 5, 6, 7, 8 /)
!!Now initialize the fcc primitive cell
@ -491,4 +491,132 @@ module elements
end do
end subroutine
recursive subroutine parse_pos(i, pos_string, pos)
!This subroutine parses the pos command allowing for command which include inf
integer, intent(in) :: i !The dimension of the position
character(len=100), intent(in) :: pos_string !The position string
real(kind=dp), intent(out) :: pos !The output parsed position value
integer :: iospara, face, ele
real(kind=dp) :: rand, rone, rtwo, rand_ele_pos(3)
character(len=100) :: cone, ctwo
iospara = 0
if(trim(adjustl(pos_string)) == 'inf') then
pos=box_bd(2*i)
else if(trim(adjustl(pos_string)) == '-inf') then
pos=box_bd(2*i-1)
else if (trim(adjustl(pos_string)) == 'rand') then
call random_number(rand)
pos = (box_bd(2*i)-box_bd(2*i-1))*rand + box_bd(2*i-1)
else if (index(pos_string,'rande')>0) then
!First select a random element
call random_number(rand)
ele= 1 + floor(ele_num*rand)
!Now read the rest of the command which specifies the face we need and check
!to make sure it's an accepted face number
cone = pos_string(index(pos_string, '[')+1:index(pos_string, '[')+1)
read(cone, *) face
if ((face < 1).or.(face > 6)) stop "Current face number must be 1,2,3,4,5,6. Please check documentation"
!Now get the position
call offset_pos(ele, face, rand_ele_pos)
pos = rand_ele_pos(i)
else if (index(pos_string,'rand')>0) then
call random_number(rand)
cone = pos_string(index(pos_string, '[')+1:index(pos_string,':')-1)
call parse_pos(i, cone, rone)
ctwo = pos_string(index(pos_string, ':')+1:index(pos_string,']')-1)
call parse_pos(i, ctwo, rtwo)
pos = (rtwo - rone)*rand + rone
else if ((index(pos_string,'-') > 0).and.(index(pos_string,'inf')>0)) then
!Now extract the number we are reducing from infinity
if(index(pos_string,'inf') < index(pos_string,'-')) then
read(pos_string(index(pos_string,'-')+1:), *, iostat=iospara) pos
else
read(pos_string(1:index(pos_string,'-')-1), *, iostat=iospara) pos
end if
pos = box_bd(2*i) - pos
else if ((index(pos_string,'+') > 0).and.(index(pos_string,'inf')>0)) then
!Now extract the number we are reducing from infinity
if(index(pos_string,'inf') < index(pos_string,'+')) then
read(pos_string(index(pos_string,'+')+1:), *, iostat=iospara) pos
else
read(pos_string(1:index(pos_string,'+')-1), *, iostat=iospara) pos
end if
pos = box_bd(2*i-1) + pos
else if ((index(pos_string,'*') > 0).and.(index(pos_string,'inf')>0)) then
!Now extract the number we are reducing from infinity
if(index(pos_string,'inf') < index(pos_string,'*')) then
read(pos_string(index(pos_string,'*')+1:), *, iostat=iospara) pos
else
read(pos_string(1:index(pos_string,'*')-1), *, iostat=iospara) pos
end if
pos = (box_bd(2*i)-box_bd(2*i-1))*pos + box_bd(2*i-1)
else
read(pos_string, *, iostat=iospara) pos
end if
if (iospara > 0) then
print *, "Error reading position argument ", trim(adjustl(pos_string)), ". Please reformat and try again."
end if
end subroutine parse_pos
subroutine offset_pos(ie, iface, pos)
!This returns a position slightly offset from the center of an element face
!This is used to return a random position within an element discontinuity
integer, intent(in) :: ie !Element index
integer, intent(in) :: iface !Face number between 1 and 6
real(kind=dp), dimension(3), intent(out) :: pos !Position vector
!Other variables we need
integer :: esize
real(kind=dp) :: orient(3,3), ori_inv(3,3), lp, r_cubic_node(3,8)
!First find the offset vector for the face in the untransformed cubic cell
esize = size_ele(ie)
select case(iface)
case(1)
pos = (/ real(esize-1,dp)/2.0_dp, real(esize-1,dp)/2.0_dp, -10.0_dp**-2.0_dp /)
case(2)
pos = (/ real(esize-1,dp)/2.0_dp, -10.0_dp**-2.0_dp, real(esize-1,dp)/2.0_dp /)
case(3)
pos = (/ (esize-1)+10.0_dp**-2.0_dp, real(esize-1,dp)/2.0_dp, real(esize-1,dp)/2.0_dp /)
case(4)
pos = (/ real(esize-1,dp)/2.0_dp, (esize-1)+10.0_dp**-2.0_dp, real(esize-1,dp)/2.0_dp /)
case(5)
pos = (/ -10.0_dp**-2.0_dp, real(esize-1,dp)/2.0_dp, real(esize-1,dp)/2.0_dp /)
case(6)
pos = (/ real(esize-1,dp)/2.0_dp, real(esize-1,dp)/2.0_dp, (esize-1)+10.0_dp**-2.0_dp /)
end select
!Now transform it to real space and adjust it to the position of the element in the first node.
select case (trim(adjustl(type_ele(ie))))
case('fcc')
!First we have to extract the element lattice parameter
call matrix_inverse(sub_box_ori(:,:,sbox_ele(ie)),3,ori_inv)
r_cubic_node = r_node(:,1,:,ie)
r_cubic_node = matmul(fcc_inv,matmul(ori_inv,r_cubic_node))
lp = (maxval(r_cubic_node(1,:))-minval(r_cubic_node(1,:)))/(esize-1)
pos = matmul(sub_box_ori(:,:,sbox_ele(ie)),matmul(fcc_mat,pos))*lp
pos = pos + r_node(:,1, 1, ie)
case default
print *, trim(adjustl(type_ele(ie))), " is not a currently accepted element type for random element positions"
stop 3
end select
end subroutine
end module elements

@ -730,7 +730,7 @@ module io
do i = 1, in_atoms
read(11,*) j, type, sbox, r(:)
r = r+newdisplace
call add_atom(new_type_to_type(type), sbox, r)
call add_atom(new_type_to_type(type), sbox+sub_box_num, r)
end do
!Read the elements
@ -742,7 +742,7 @@ module io
r_innode(:,ibasis,inod) = r_innode(:, ibasis, inod) + newdisplace
end do
end do
call add_element(etype, size, new_lattice_map(type), sbox+n, r_innode)
call add_element(etype, size, new_lattice_map(type), sbox+sub_box_num, r_innode)
end do
!Close the file being read

@ -171,67 +171,7 @@ module subroutines
return
end subroutine parse_ori_vec
recursive subroutine parse_pos(i, pos_string, pos)
!This subroutine parses the pos command allowing for command which include inf
integer, intent(in) :: i !The dimension of the position
character(len=100), intent(in) :: pos_string !The position string
real(kind=dp), intent(out) :: pos !The output parsed position value
integer :: iospara
real(kind=dp) :: rand, rone, rtwo
character(len=100) :: cone, ctwo
iospara = 0
if(trim(adjustl(pos_string)) == 'inf') then
pos=box_bd(2*i)
else if(trim(adjustl(pos_string)) == '-inf') then
pos=box_bd(2*i-1)
else if (trim(adjustl(pos_string)) == 'rand') then
call random_number(rand)
pos = (box_bd(2*i)-box_bd(2*i-1))*rand + box_bd(2*i-1)
else if (index(pos_string,'rand')>0) then
call random_number(rand)
cone = pos_string(index(pos_string, '[')+1:index(pos_string,':')-1)
call parse_pos(i, cone, rone)
ctwo = pos_string(index(pos_string, ':')+1:index(pos_string,']')-1)
call parse_pos(i, ctwo, rtwo)
pos = (rtwo - rone)*rand + rone
else if ((index(pos_string,'-') > 0).and.(index(pos_string,'inf')>0)) then
!Now extract the number we are reducing from infinity
if(index(pos_string,'inf') < index(pos_string,'-')) then
read(pos_string(index(pos_string,'-')+1:), *, iostat=iospara) pos
else
read(pos_string(1:index(pos_string,'-')-1), *, iostat=iospara) pos
end if
pos = box_bd(2*i) - pos
else if ((index(pos_string,'+') > 0).and.(index(pos_string,'inf')>0)) then
!Now extract the number we are reducing from infinity
if(index(pos_string,'inf') < index(pos_string,'+')) then
read(pos_string(index(pos_string,'+')+1:), *, iostat=iospara) pos
else
read(pos_string(1:index(pos_string,'+')-1), *, iostat=iospara) pos
end if
pos = box_bd(2*i-1) + pos
else if ((index(pos_string,'*') > 0).and.(index(pos_string,'inf')>0)) then
!Now extract the number we are reducing from infinity
if(index(pos_string,'inf') < index(pos_string,'*')) then
read(pos_string(index(pos_string,'*')+1:), *, iostat=iospara) pos
else
read(pos_string(1:index(pos_string,'*')-1), *, iostat=iospara) pos
end if
pos = (box_bd(2*i)-box_bd(2*i-1))*pos + box_bd(2*i-1)
else
read(pos_string, *, iostat=iospara) pos
end if
if (iospara > 0) then
print *, "Error reading position argument ", trim(adjustl(pos_string)), ". Please reformat and try again."
end if
end subroutine parse_pos
subroutine heapsort(a)

Loading…
Cancel
Save