Skip to content

B. An advanced example: flake with random vacancies

Gabriele Bellomia edited this page Feb 3, 2024 · 3 revisions

If you need finer control and/or customization you can directly use the low-level modules:

To do that it is strongly advised to look carefully at the full API documentation. As a demonstration of the flexibility of the package we report here one notable example.

How to build hexagonal flakes with random vacancies?

program random_vacancies

   use hex_coordinates
   use hex_layout
   use hex_geometries
   use xy_coordinates
   use xy_neighbors
   use honeyplots, only: plot

We import honeyplots too, so to have access to the visualization facilities, but that's not necessary to build the lattice and the neighbor-shells/masks.

Let's start declaring a lattice object, a unit-cell, and a orientation object. Finally two logical masks and two 2D-real arrays, to define our custom unit-vectors and collect the nearest/next-nearest neighbors information.

   implicit none

   type(xy_lattice)        :: lattice
   type(unit_cell)         :: mycell
   logical,allocatable     :: NN(:,:),NNN(:,:)
   real(8)                 :: e1(2),e2(2)
   type(hex_orientation)   :: mybasis

So let's define our custom unit-cell as:

   ! Custom lattice unit vectors
   e1 = 3d0/2d0*[1d0, 1d0/sqrt(3d0)]
   e2 = 3d0/2d0*[1d0,-1d0/sqrt(3d0)]

   ! Define the hex_orientation object
   mybasis = hex_orientation(uq=e1,ur=e2,angle=1d0)

   ! Init the unit-cell with a custom lattice spacing
   mycell = unit_cell(mybasis,size=10,origin=[0,0])

And call a hand-crafted builder for our "holed" flake!

   ! Call the special custom builder: get_holed_flake
   lattice = get_holed_flake(10,mycell)
   call xy_next_nearest_neighbors(lattice,NNN,NN)
   call plot(lattice,NN,figure_name='holed1.svg')
   call plot(lattice,NN,NNN,figure_name='holed2.svg')

contains

   impure function get_holed_flake(radius,layout) result(flake)
      !! Build a hexagon-shaped honeycomb flake, with random vacancies!
      integer,intent(in)            :: radius
      type(unit_cell),intent(in)    :: layout
      type(xy_lattice)              :: flake
      type(hex),allocatable         :: hexagons(:)
      integer                       :: i,j,k
      real(8)                       :: u
      do i = -radius,+radius
         do j = max(-radius,-i-radius),min(radius,-i+radius)
            k = randi(i,j)
            if(mod(k,2)/=0)then
               call hex_insert(hexagons,hex(i,j))
            endif
         enddo
      enddo
      flake = hex2lattice(mycell,hexagons)
   end function

   !> Generate random integer in {p,p+1,…,q}
   impure integer function randi(p,q)
      integer,intent(in)   :: p,q
      real(8)              :: r
      call random_number(r)
      randi = p + floor((q+1-p)*r)
   end function

end program random_vacancies

This would output:

Realization #1 #2 #3
NN-bonds only holed1_custom holed1_another holed1
NN+NNN links holed2_custom holed2_another holed2

You can run the entire program (and so get other realizations) with the fpm test "advanced_api" command, from any folder of your git clone (the fortran package manager is git aware).


Note that the custom unit-cell is not necessary to the main focus of the program, you could just request

mycell = unit_cell(armchair,size=10)

and get the same qualitative results. So here we show what would be the results for:

mycell=unit_cell(zigzag)
Realization #1 #2
NN-bonds only holed_zigzag1_NN holed_zigzag2_NN
NN+NNN links holed_zigzag1_NNN holed_zigzag2_NNN