VASP PROCAR split script (밴드구조에서 원자점유 표현하기)
Dec. 3, 2019 /
2 mins read /
PROCAR split script
예전에 VASP 계산을 하던 도중, PROCAR 파일에서 데이터를 추출해야 할 필요가 있었습니다.
위 이미지처럼 Band structure에서 각 원자별로 Band structure에 기여를 (Orbital-projected band structure) 나타내려고 했었는데요.
그래서 열심히 스크립트를 짰는데, 결과물은 별로 맘에 안들었고, 코드는 코드대로 엉망이였습니다. 그리고 나중에 보니 이런 게 이미 있었습니다.. 😐
며칠간의 삽질을 통해 깨달은 건, 역시 뭐든지 검색을 잘 하고 주변 고수들에게 많이 물어봐야 한다는 점입니다. 😂
C shell
#!/bin/csh
# Script to split the PROCAR file by each k-points
echo "how many number of atom?"
set ion = $<
echo "how many number of band?(NBANDS)"
set band = $<
set bandlist = `seq 1 $band`
set inputfile = PROCAR
if (-e $inputfile) then
echo " The" $inputfile "exists, keep going..."
else
echo $inputfile " file doesn't exist... please check" $inputfile
exit 0
endif
rm -rf PROCARtemp
mkdir PROCARtemp
cp $inputfile ./PROCARtemp
cd ./PROCARtemp
# split PROCAR file -> each k-point
#####################################################################
set kpoint = `grep "k-point" $inputfile | cut -d " " -f 2`
set kpoint_line = `grep -n "k-point" $inputfile | cut -d ":" -f 1`
rm -f kpoint_number
echo $kpoint_line >> kpoint_number
set kpoint_ini = `awk '{print $2}' kpoint_number`
set kpoint_fin = `awk '{print $3}' kpoint_number`
set kpoint_range = `expr $kpoint_fin - $kpoint_ini`
set no = 0
foreach i ($kpoint_line)
echo "bandline split... "$no
set ii = `expr $i + $kpoint_range`
set ii = `expr $ii - 1`
rm -f "kpoint"$no
sed -n $i,${ii}p $inputfile >> "kpoint"$no
set no = `expr $no + 1`
end
rm -f "kpoint"0
rm -f kpoint_number
#####################################################################
# each k-point files -> split each band
#####################################################################
set kpoint_inputfile = kpoint
set kpointlist = `ls | grep "kpoint" | cut -d 't' -f 2`
foreach kpoint ($kpointlist)
set kpoint_no = $kpoint
echo "k-ponit "$kpoint_no "split ing..."
#
# check number of ions
#
set ion_line = `grep -n "ion" $kpoint_inputfile$kpoint_no | cut -d ":" -f 1`
rm -f ionnumber
echo $ion_line | cut -d " " -f 1- >> ionnumber
set ion_ini = `awk '{print $1}' ionnumber`
set ion_fin = `awk '{print $2}' ionnumber`
set ion_range = `expr $ion_ini + $ion`
#####################################################################
# split occupation for each atoms at each bands
#####################################################################
set b = 1
set c = 2
set no_band = `cat ionnumber | wc -w`
set listofatoms = `seq 1 2 $no_band`
rm -f ionsplit
if (-e ionsplit_temp\*) then
rm -f ionsplit_temp*
else
endif
rm -f ionsplit_fin$kpoint_no
foreach x ($listofatoms)
set ion_ini = `awk -v x="$x" '{print $x}' ionnumber`
#set ion_ini = `expr $ion_ini + 1`
set y = `expr $x + 1`
set ion_fin = `awk -v y="$y" '{print $y}' ionnumber`
set ion_range = `expr $ion_ini + $ion`
#echo $ion_ini "ini " $ion_fin "fin " $ion_range "range " $i $j
#set ion_no =
set noofatom = `seq $ion_ini $ion_range`
foreach k ($noofatom)
sed -n ${k}p ${kpoint_inputfile}$kpoint_no >> ionsplit_temp_${kpoint_no}_${k} #
end
set b = `expr $b + 2`
set c = `expr $c + 2`
end
# assemble occupation for each atoms at each bands
#############################################################################
set b = 1
set c = 2
set mergeatoms = `ls -v | grep "ionsplit_temp_${kpoint}" | cut -d '_' -f 3`
echo $mergeatoms
foreach x ($mergeatoms)
set ion_ini = `awk -v x="$x" '{print $x}' ionnumber`
set y = `expr $x + 1`
set ion_fin = `awk -v y="$y" '{print $y}' ionnumber`
set ion_range = `expr $ion_ini + $ion`
set noofatom = `seq $ion_ini $ion_range`
foreach k ($noofatom)
set kk = `expr $k + 1`
if (-e ionsplit_temp_${kpoint_no}_${kk}) then
cat ionsplit_temp_${kpoint_no}_${kk} >> ionsplit_temp_${kpoint_no}_$ion_ini
else
endif
end
set b = `expr $b + 2`
set c = `expr $c + 2`
cat ionsplit_temp_${kpoint_no}_${ion_ini} >> ionsplit_fin_${kpoint_no}
#echo ionsplit_temp${ion_ini}
end
############################################################################
rm -f ionsplit_temp*
cat ionsplit_fin_${kpoint_no} | tr "\n" "\t" | sed 's/\tion/\nion/g' > ../PROCAR_kpoint${kpoint_no}
end
cd ..
set merge_input = PROCAR_kpoint
set mergelist = `ls -v | grep "PROCAR_kpoint" | cut -d 't' -f 2`
set input_linemax = `grep -c '\n' PROCAR_kpoint1`
set input_lineno = `seq 1 $input_linemax`
rm -rf PROCAR_result
foreach m ($mergelist)
foreach n ($input_lineno)
echo `sed -n ${n}p $merge_input$m` >> PROCAR_result
end
echo "" >> PROCAR_result
end
#rm -rf PROCARtemp
echo "done!"
당시엔 뭐 이런식으로 스크립트를 짰었는데요. 사실 너무 코드가 엉망진창이지만, 기록을 남겨놓아야 같은 실수를 반복하지 않으니.. 하고 올려봅니다.
아참, 혹시라도 PROCAR 를 분석하는 툴이 필요하다면 무료소프트웨어인 p4v를 추천해드립니다.