Skip to content

Commit 21fb3d0

Browse files
committed
DDEC6 charge evaluation added
1 parent 4894a9e commit 21fb3d0

1 file changed

Lines changed: 185 additions & 2 deletions

File tree

evaluation/analyze_dft.f90

Lines changed: 185 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ program analyze_dft
1414
integer::i
1515
character(len=120)::cdum,arg
1616
logical::switch_bader,switch_stm,switch_pdos,switch_cls
17+
logical::switch_ddec6
1718
!
1819
! only print the overview of utils4VASP scripts/programs and stop
1920
!
@@ -61,6 +62,7 @@ program analyze_dft
6162
write(*,*) " details and more detailed commands."
6263
write(*,*) "The following command line arguments can be given:"
6364
write(*,*) " -bader: Evaluates a Bader charge calculation "
65+
write(*,*) " -ddec6: Evaluates a DDEC6 charge calculation "
6466
write(*,*) " -pdos: partial density of states calculations are evaluated"
6567
write(*,*) " -stm: generates STM images from surface calculations."
6668
write(*,*) " -cls: Set up and evaluate core level shift calculations for"
@@ -79,6 +81,17 @@ program analyze_dft
7981
end if
8082
end do
8183

84+
!
85+
! If a DDEC6 charge calculation shall be evaluated
86+
!
87+
switch_ddec6 = .false.
88+
do i = 1, command_argument_count()
89+
call get_command_argument(i, arg)
90+
if (trim(arg(1:6)) .eq. "-ddec6") then
91+
switch_ddec6 = .true.
92+
end if
93+
end do
94+
8295
!
8396
! If a STM calculation shall be evaluated
8497
!
@@ -113,7 +126,8 @@ program analyze_dft
113126
end do
114127

115128
if ((.not. switch_bader) .and. (.not. switch_stm) .and. &
116-
& (.not. switch_pdos) .and. (.not. switch_cls)) then
129+
& (.not. switch_pdos) .and. (.not. switch_cls) .and. &
130+
& (.not. switch_ddec6)) then
117131
write(*,*)
118132
write(*,*) "Please give one of the calculation types!"
119133
write(*,*)
@@ -127,6 +141,10 @@ program analyze_dft
127141
call calc_bader
128142
end if
129143

144+
if (switch_ddec6) then
145+
call calc_ddec6
146+
end if
147+
130148
if (switch_stm) then
131149
call calc_stm
132150
end if
@@ -540,7 +558,7 @@ subroutine calc_bader
540558
! Print out individual Bader partial charges to separate file
541559
!
542560
open(unit=19,file="bader_charges.dat")
543-
write(19,*) "# Bader charges of all atoms, written by eval_bader"
561+
write(19,*) "# Bader charges of all atoms, written by analyze_dft"
544562
write(19,*) "# index charge(e)"
545563
do i=1,natoms
546564
write(19,'(i9,f15.8)') i, charge_list(i)
@@ -596,6 +614,171 @@ subroutine calc_bader
596614
end subroutine calc_bader
597615

598616

617+
!
618+
! calc_bader: evaluates the result of a DDEC6 charge calculation
619+
! with the chargemol program based on the CHGCAR and AECCAR
620+
! VASP output files.
621+
! The file DDEC6_even_tempered_atomic_charges.xyz needs to be present
622+
!
623+
624+
subroutine calc_ddec6
625+
implicit none
626+
integer::i,j,k
627+
integer::readstat
628+
integer::natoms,nelems
629+
real(kind=8),allocatable::xyz(:,:)
630+
real(kind=8),allocatable::charge_list(:)
631+
character(len=2),allocatable::at_names(:),el_names(:)
632+
integer,allocatable::el_nums(:)
633+
character(len=2)::el_names_tmp(50)
634+
real(kind=8)::a_vec(3),b_vec(3),c_vec(3)
635+
real(kind=8),allocatable::charge_avg(:)
636+
character(len=20)::adum
637+
logical::el_exist
638+
!
639+
! Print general information and all possible keywords of the program
640+
!
641+
write(*,*)
642+
write(*,*) "Option -ddec6: evaluation of DDEC6 charge calculations"
643+
write(*,*) " from preprocessed VASP output for arbitrary systems."
644+
write(*,*) "Before starting the analysis, the files AECCAR0, AECCAR2 and "
645+
write(*,*) " CHGCAR must be present as output and evaullated with the "
646+
write(*,*) " Chargemol program from T. Manz et al.:"
647+
write(*,*) " https://sourceforge.net/projects/ddec/files/"
648+
write(*,*) "Read the tutorial there or in the utils4VASP wiki on how "
649+
write(*,*) " run that evaluation."
650+
write(*,*) "After this, the fie DDEC6_even_tempered_net_atomic_charges.xyz"
651+
write(*,*) " should be present."
652+
write(*,*) "Now, start this program. "
653+
write(*,*)
654+
!
655+
! Read in relevant informations from Chargemol output file
656+
!
657+
open(unit=45,file="DDEC6_even_tempered_net_atomic_charges.xyz", &
658+
& status="old",iostat=readstat)
659+
if (readstat .ne. 0) then
660+
write(*,*) "The file DDEC6_even_tempered_net_atomic_charges.xyz is missing!"
661+
write(*,*)
662+
stop
663+
end if
664+
read(45,*) natoms
665+
allocate(xyz(3,natoms))
666+
allocate(charge_list(natoms))
667+
allocate(at_names(natoms))
668+
669+
read(45,*) adum,adum,adum,adum,adum,adum,adum,adum,adum,adum,&
670+
& a_vec(:),adum,adum,b_vec(:),adum,adum,c_vec(:)
671+
do i=1,natoms
672+
read(45,*) at_names(i),xyz(:,i),charge_list(i)
673+
end do
674+
close(45)
675+
!
676+
! Determine number of elements in the system
677+
!
678+
nelems=0
679+
do i=1,natoms
680+
el_exist=.false.
681+
do j=1,nelems
682+
if (trim(at_names(i)) .eq. trim(el_names_tmp(j))) then
683+
el_exist=.true.
684+
end if
685+
end do
686+
if (.not. el_exist) then
687+
nelems=nelems+1
688+
el_names_tmp(nelems)=at_names(i)
689+
end if
690+
end do
691+
allocate(el_names(nelems))
692+
allocate(el_nums(nelems))
693+
allocate(charge_avg(nelems))
694+
el_names(:)=el_names_tmp(1:nelems)
695+
el_nums=0
696+
697+
!
698+
! Determine number of atoms for each element
699+
!
700+
do i=1,natoms
701+
do j=1,nelems
702+
if (trim(at_names(i)) .eq. trim(el_names(j))) then
703+
el_nums(j) = el_nums(j) + 1
704+
end if
705+
end do
706+
end do
707+
!
708+
! Calculate the average charges
709+
!
710+
charge_avg=0.d0
711+
do i=1,natoms
712+
do j=1,nelems
713+
if (trim(at_names(i)) .eq. trim(el_names(j))) then
714+
charge_avg(j)=charge_avg(j)+charge_list(i)
715+
end if
716+
end do
717+
end do
718+
do j=1,nelems
719+
charge_avg(j)=charge_avg(j)/el_nums(j)
720+
end do
721+
722+
!
723+
! Print out individual DDEC6 partial charges to separate file
724+
!
725+
open(unit=19,file="ddec6_charges.dat")
726+
write(19,*) "# DDEC6 charges of all atoms, written by analyze_dft"
727+
write(19,*) "# index charge(e)"
728+
do i=1,natoms
729+
write(19,'(i9,f15.8)') i, charge_list(i)
730+
end do
731+
732+
close(19)
733+
write(*,*) "DDEC6 charges of atoms written to 'ddec6_charges.dat'."
734+
735+
!
736+
! Print out structure and charges together to file charges.pdb
737+
! (can be used for VMD visualization)
738+
!
739+
open(unit=20,file="charges.pdb")
740+
write(20,'(a)') "COMPND FINAL HEAT OF FORMATION = 0.000000"
741+
write(20,'(a)') "AUTHOR GENERATED BY PROGRAM EVAL BADER"
742+
do i=1,natoms
743+
write(20,'(a,i5,a,a,a,3f8.3,f7.3,f5.2,a,a)') "HETATM",i," ",at_names(i), &
744+
& " UNL 1 ",xyz(:,i),charge_list(i),0d0," ",at_names(i)
745+
end do
746+
write(20,*) "MASTER 0 0 0 0 0 0 0 0 180 0 180 0"
747+
write(20,*) "END"
748+
close(20)
749+
write(*,*) "File with coordinates and charges written to 'charges.pdb'"
750+
write(*,*) " Open this file with VMD and select 'coloring method: occupancy'"
751+
752+
open(unit=21,file="POSCAR_charge")
753+
write(21,*) "POSCAR file with charges, written by analyze_dft"
754+
write(21,*) 1.0
755+
write(21,*) a_vec(:)
756+
write(21,*) b_vec(:)
757+
write(21,*) c_vec(:)
758+
do i=1,nelems
759+
write(21,'(a,a)',advance="no") " ",el_names(i)
760+
end do
761+
write(21,*)
762+
write(21,*) el_nums(:)
763+
write(21,*) "Cartesian"
764+
do i=1,natoms
765+
write(21,'(4f23.15)') xyz(:,i),charge_list(i)
766+
end do
767+
close(21)
768+
write(*,*) "File with coordinates and charges written to 'POSCAR_charge'"
769+
write(*,*)
770+
!
771+
! Print out resulting average charges
772+
!
773+
774+
write(*,*) "The resulting average charges are:"
775+
do i=1,nelems
776+
write(*,'(3a,f12.6)') " -",el_names(i),": ",charge_avg(i)
777+
end do
778+
779+
780+
end subroutine calc_ddec6
781+
599782
!
600783
! calc_stm: evaluates the results of a STM calculation
601784
! (partial charge density, to be evaluated by the Tersoff-Hamann

0 commit comments

Comments
 (0)