本帖最后由 丁越 于 2022-8-6 00:19 编辑
QE中批量固定原子的小脚本QEfix.sh
虽然在pwgui中提供了固定原子的选项,但是一个一个地固定原子坐标显得颇为麻烦,遂写了个小脚本可以很方便的固定原子坐标。脚本的使用很简单,例如将rutile的结构载入gview中,然后选择所要固定的原子后,在tools -> atom selection中就可以复制所要固定原子的序号了。接下来,通过pwgui生成如结构优化输入文件rutile.relax.in(不需要固定原子),然后执行 ./QEfix.sh rutile.relax.in 后,脚本首先会提示需要固定原子的序号,粘贴回车;紧接着会提示如何固定,如输入 0 0 0就表示将x、y、z三个方向同时固定。 接下来说说脚本的思路:原子的序号样式是这样的 2,3,4-10,因此,首先我们需要将这些序号拆解成一个一个的单个序号形式(2,3,4,5....10),然后写个for循环在批量去在每个需要固定的原子后面添加如0 0 0。拆解原子序号时,我们先用awk以逗号为分割符将其拆开,然后存进第一个临时文件tmp1.dat;接下来,我们需要判断tmp1.dat中数据假如是单个数字的,那就直接把它存进临时文件tmp2.dat中,假如是以4-10这样的数据,我们设置Min=4,Max=10,然后利用for循环把Min~Max中的数据缀加到tmp2中,此时,整个原子序号就被拆解成了单个序号存进了tmp2.dat中。接下来,由于输入文件中第一个原子所在行数不是1,那么我们还需要将tmp2.dat数据都加上行数得到tmp3.dat; 最后,再次利用for循环按照tmp3.dat中原子所在行数去添加如0 0 0。脚本中,[ "$i" =~ ^[0-9]+$ ]是比较常用的判断字符串包含关系的语法。sed -i "${i}s/$/${if_pos}/g" $1中$表示行尾,s表示替换,g为global,$1意思是脚本文件接受的第一个参数。
- #!/bin/bash
- #usage: QEfix.sh [qe input file]
- fname1=`echo $1`
- echo ' Input indices of the atoms to be constraint (fixed), e.g. 1,5,9-12,14-18: '
- read num
- echo ' Input if_pos(i), e.g. 0 0 0, which means atomic coordinates at x, y, and z direction will be fixed simutaneously:'
- read if_pos
- echo
- pos=`grep -n ATOMIC_POSITIONS ${fname1} |cut -d ":" -f 1 |head -1`
- echo $num|awk -F , '{for(i=1;i<=NF;i++) print $i}' > ${prefix}_tmp1.dat
- #Generating the atoms Index into tmp2.dat
- for i in $(cat ${prefix}_tmp1.dat);do
- if [[ "$i" =~ ^[0-9]+$ ]];then
- echo $i >> ${prefix}_tmp2.dat
- else
- Min=$(echo $i |awk -F \- '{print $1}')
- Max=$(echo $i |awk -F \- '{print $2}')
- for j in $(seq $Min $Max)
- do
- echo $j >> ${prefix}_tmp2.dat
- done
- fi
- done
- #fixing atoms in the QE input file
- for i in $(cat ${prefix}_tmp2.dat)
- do
- line=$(($i + $pos))
- echo $line >> ${prefix}_tmp3.dat
- done
- for i in $(cat ${prefix}_tmp3.dat)
- do
- sed -i "${i}s/$/ ${if_pos}/g" ${fname1}
- done
- rm -f ${prefix}_tmp*
复制代码
|